sql >> Databasteknik >  >> RDS >> Sqlserver

Varför ignorerar Query Optimizer totalt indexerade vyindex?

tl;dr svar:Om du inte anger NOEXPAND, har frågeoptimeraren ingen aning om att du skickar ett enkelt urval från en vy. Den måste matcha expansionen av din fråga (vilket är allt den ser) med något vyindex. Kommer antagligen inte att bry sig när det är en femvägs sammanfogning med ett gäng casts.

Visa indexmatchning till en fråga är ett svårt problem, och jag tror att din vy är för komplicerad för att sökmotorn ska kunna matcha ett index. Tänk på denna av dina frågor:

SELECT ID, Code1 FROM EntityView Where Code1 > 'NR%';

Det är uppenbart för dig att detta kan använda ett vyindex, men det är inte frågan som sökmotorn ser. Vyerna utökas automatiskt om du inte anger NOEXPAND, så det här är vad som går till frågemotorn:

SELECT ID, Code1 FROM (
    SELECT e.ID, 'NR'+CAST(c1.CODE as nvarchar(11)) as Code1, 'NR'+CAST(c2.CODE as nvarchar(11)) as Code2, 'NR'+CAST(c3.CODE as nvarchar(11)) as Code3, 'NR'+CAST(c4.CODE as nvarchar(11)) as Code4, 'NR'+CAST(c5.CODE as nvarchar(11)) as Code5
    FROM dbo.Entity e
        inner join  dbo.Classificator1 c1 on e.ID = c1.ID
        inner join  dbo.Classificator2 c2 on e.ID = c2.ID
        inner join  dbo.Classificator3 c3 on e.ID = c3.ID
        inner join  dbo.Classificator4 c4 on e.ID = c4.ID
        inner join  dbo.Classificator5 c5 on e.ID = c5.ID;
) AS V;

Frågemotorn ser den här komplicerade frågan och den har information (men förmodligen inte SQL of view definitioner) som beskriver vyindex som har definierats. Med tanke på att den här frågan och vyindexen båda har flera kopplingar och casts är matchning ett svårt jobb.

Tänk på att du vet att kopplingarna och matchningarna är identiska i den här frågan och vyindexen, men det vet inte frågeprocessorn. Den behandlar den här frågan på samma sätt som om den sammanfogade fem kopior av Classificator3, eller om en av kolumnerna var 'NQ'+CAST(c2.CODE som varchar(12)). Visningsindexmatcharen (förutsatt att den gjorde något försök att matcha denna komplicerade fråga) skulle behöva matcha varje detalj i denna fråga med detaljerna i vyindexen i de inblandade tabellerna.

Frågemotorn har som sitt #1 mål att ta reda på ett sätt att exekvera frågan effektivt. Det är förmodligen inte utformat för att spendera mycket tid på att försöka matcha varje detalj i en femvägskoppling och CAST till ett visningsindex.

Om jag var tvungen att gissa, misstänker jag att visningsindexmatcharen ser att resultatkolumnerna i frågan inte ens är kolumner i någon underliggande tabell (på grund av CAST) och helt enkelt inte bryr sig om att prova någonting. Tillagt :Jag har fel. Jag försökte precis Martins förslag att uppdatera statistik för att göra frågan dyr, och ett vyindex matchades för några av dessa frågor utan NOEXPAND. Visningsmatcharen är smartare än jag trodde! Så problemet är att visningsmatcharen förmodligen försöker matcha en komplicerad fråga om kostnaden är mycket hög.

Använd NOEXPAND-tipset istället för att förvänta dig att frågemotorn ska kunna ta reda på vad som matchar här. NOEXPAND är absolut din vän, för då får frågemotorn se

SELECT ID, Code1 FROM EntityView Where Code1 > 'NR%';

och det är då direkt uppenbart för visningsindexmatcharen att det finns ett användbart index.

(Obs! Din SQL Fiddle-kod har alla fem främmande nyckelreferenser till samma tabell, vilket förmodligen inte är vad du vill ha.)



  1. ora-01722 ogiltigt nummer använder count(1) på minusoperatorn för två vyer

  2. Hur grupperar man efter datum med ett tidsstämpelfält i Postgres?

  3. Rensa rubriken i Oracle-spolen

  4. Hur man hämtar databasschemat för en lagrad procedur