In breve
Quali sono i fattori che influenzano la selezione di Optimizer dall'indice di una vista indicizzata?
Per me, le viste indicizzate sembrano sfidare ciò che ho capito su come lo Strumento per ottimizzare sceglie gli indici. L'ho già visto prima , ma l'OP non è stato accolto molto bene. Sto davvero cercando guide , ma inventerò uno pseudo esempio, quindi pubblicherò un esempio reale con un sacco di DDL, output, esempi.
Supponiamo che sto usando Enterprise 2008+, capire
with(noexpand)
Esempio di pseudo
Prendi questo pseudo esempio: creo una vista con 22 join, 17 filtri e un pony circus che attraversa un gruppo di 10 milioni di tabelle di righe. Questa visione è costosa (sì, con la E maiuscola) da materializzare. SCHEMABIND e indicizzerò la vista. Quindi a SELECT a,b FROM AnIndexedView WHERE theClusterKeyField < 84
. Nella logica di Optimizer che mi sfugge vengono eseguiti i join sottostanti.
Il risultato:
- Nessun suggerimento: 4825 letture per 720 righe, 47 cpu su 76ms e un costo sotto l'albero stimato di 0,30523.
- Con suggerimento: 17 letture, 720 righe, 15 cpu su 4ms e un costo sottotree stimato di 0,007253
Quindi cosa sta succedendo qui? L'ho provato in Enterprise 2008, 2008-R2 e 2012. Secondo ogni metrica posso pensare di utilizzare l'indice della vista in modo molto più efficiente. Non ho problemi di sniffing dei parametri o dati distorti, dato che si tratta di un trampolino pubblicitario.
Un esempio reale (lungo)
A meno che tu non sia un tocco masochista, probabilmente non hai bisogno o non vuoi leggere questa parte.
La versione
Sì, impresa.
Microsoft SQL Server 2012 - 11.0.2100.60 (X64) 10 feb 2012 19:39:15 Copyright (c) Microsoft Corporation Enterprise Edition (64 bit) su Windows NT 6.2 (build 9200:) (Hypervisor)
La vista
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
Indice cluster
CREATE UNIQUE CLUSTERED INDEX PK_TimelineMaterialized ON
TimelineMaterialized (EmployeeID, CreateUTC, CultureCode, TimelineID)
Test 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'
Risultato = 11 righe di output
Output del profiler
Le prime 4 righe sono prive di suggerimenti. Le 4 righe inferiori utilizzano il suggerimento.
Piani di esecuzione
GitHub Gist per entrambi i piani di esecuzione in formato SQLPlan
Nessun piano di esecuzione dei suggerimenti: perché non utilizzare l'indice cluster che le ho dato Mr. SQL? È clusterd sui 3 campi filtro. Provalo, potrebbe piacerti.
Piano semplice quando si utilizza un suggerimento.