Secara singkat
Faktor-faktor apa yang masuk ke dalam mereka kueri pemilihan pengoptimal dari indeks tampilan diindeks?
Bagi saya, tampilan yang diindeks tampaknya menentang apa yang saya pahami tentang bagaimana Pengoptimal mengambil indeks. Saya pernah melihat ini bertanya sebelumnya , tetapi OP tidak diterima dengan baik. Saya benar-benar mencari guidepost , tapi saya akan membuat contoh pseudo, lalu memposting contoh nyata dengan banyak DDL, output, contoh.
Asumsikan saya menggunakan Enterprise 2008+, mengerti
with(noexpand)
Contoh semu
Ambil contoh semu ini: Saya membuat tampilan dengan 22 gabungan, 17 filter, dan poni sirkus yang melintasi sekelompok 10 juta tabel baris. Pandangan ini mahal (ya, dengan huruf besar E) untuk terwujud. Saya akan SCHEMABIND dan Indeks tampilan. Lalu a SELECT a,b FROM AnIndexedView WHERE theClusterKeyField < 84
. Dalam logika Pengoptimal yang menghindari saya, gabungan yang mendasarinya dilakukan.
Hasil:
- Tidak Petunjuk: 4825 dibaca untuk 720 baris, 47 cpu lebih dari 76ms, dan perkiraan biaya sub pohon 0,30523.
- Dengan Petunjuk: 17 kali dibaca, 720 baris, 15 cpu lebih dari 4ms, dan perkiraan biaya subtree sebesar 0,007253
Jadi apa yang terjadi di sini? Saya sudah mencobanya di Enterprise 2008, 2008-R2 dan 2012. Dengan setiap metrik yang saya pikirkan menggunakan indeks tampilan jauh lebih efisien. Saya tidak memiliki masalah parameter sniffing atau data miring, karena ini ad hock.
Contoh Nyata (Panjang)
Kecuali Anda seorang masokis sentuhan, Anda mungkin tidak perlu atau ingin membaca bagian ini.
Versi
Yap, perusahaan.
Microsoft SQL Server 2012 - 11.0.2100.60 (X64) 10 Februari 2012 19:39:15 Hak cipta (c) Microsoft Corporation Enterprise Edition (64-bit) pada Windows NT 6.2 (Build 9200:) (Hypervisor)
Pandangan
CREATE VIEW dbo.TimelineMaterialized WITH SCHEMABINDING
AS
SELECT TM.TimelineID,
TM.TimelineTypeID,
TM.EmployeeID,
TM.CreateUTC,
CUL.CultureCode,
CASE
WHEN TM.CustomerMessageID > 0 THEN TM.CustomerMessageID
WHEN TM.CustomerSessionID > 0 THEN TM.CustomerSessionID
WHEN TM.NewItemTagID > 0 THEN TM.NewItemTagID
WHEN TM.OutfitID > 0 THEN TM.OutfitID
WHEN TM.ProductTransactionID > 0 THEN TM.ProductTransactionID
ELSE 0 END As HrefId,
CASE
WHEN TM.CustomerMessageID > 0 THEN IsNull(C.Name, 'N/A')
WHEN TM.CustomerSessionID > 0 THEN IsNull(C.Name, 'N/A')
WHEN TM.NewItemTagID > 0 THEN IsNull(NI.Title, 'N/A')
WHEN TM.OutfitID > 0 THEN IsNull(O.Name, 'N/A')
WHEN TM.ProductTransactionID > 0 THEN IsNull(PT_PL.NameLocalized, 'N/A')
END as HrefText
FROM dbo.Timeline TM
INNER JOIN dbo.CustomerSession CS ON TM.CustomerSessionID = CS.CustomerSessionID
INNER JOIN dbo.CustomerMessage CM ON TM.CustomerMessageID = CM.CustomerMessageID
INNER JOIN dbo.Outfit O ON PO.OutfitID = O.OutfitID
INNER JOIN dbo.ProductTransaction PT ON TM.ProductTransactionID = PT.ProductTransactionID
INNER JOIN dbo.Product PT_P ON PT.ProductID = PT_P.ProductID
INNER JOIN dbo.ProductLang PT_PL ON PT_P.ProductID = PT_PL.ProductID
INNER JOIN dbo.Culture CUL ON PT_PL.CultureID = CUL.CultureID
INNER JOIN dbo.NewsItemTag NIT ON TM.NewsItemTagID = NIT.NewsItemTagID
INNER JOIN dbo.NewsItem NI ON NIT.NewsItemID = NI.NewsItemID
INNER JOIN dbo.Customer C ON C.CustomerID = CASE
WHEN TM.TimelineTypeID = 1 THEN CM.CustomerID
WHEN TM.TimelineTypeID = 5 THEN CS.CustomerID
ELSE 0 END
WHERE CUL.IsActive = 1
Indeks Berkelompok
CREATE UNIQUE CLUSTERED INDEX PK_TimelineMaterialized ON
TimelineMaterialized (EmployeeID, CreateUTC, CultureCode, TimelineID)
Uji SQL
-- NO HINT - - - - - - - - - - - - - - -
SELECT * --yes yes, star is bad ...just a test example
FROM TimelineMaterialized TM
WHERE
TM.EmployeeID = 2
AND TM.CultureCode = 'en-US'
AND TM.CreateUTC > '9/10/2012'
AND TM.CreateUTC < '9/11/2012'
-- WITH HINT - - - - - - - - - - - - - - -
SELECT *
FROM TimelineMaterialized TM with(noexpand)
WHERE
TM.EmployeeID = 2
AND TM.CultureCode = 'en-US'
AND TM.CreateUTC > '9/10/2012'
AND TM.CreateUTC < '9/11/2012'
Hasil = 11 Baris Output
Output Profiler
4 baris teratas tanpa petunjuk. 4 baris terbawah menggunakan petunjuk.
Eksekusi Rencana
GitHub Intis untuk kedua Rencana Eksekusi dalam format SQLPlan
Tidak ada rencana Eksekusi Petunjuk - mengapa tidak menggunakan indeks berkerumun yang saya berikan kepada Anda Mr. SQL? Itu clusterd pada bidang filter 3. Cobalah, Anda mungkin menyukainya.
Paket sederhana saat menggunakan petunjuk.