sql >> Databasteknik >  >> RDS >> Sqlserver

Optimera SQL-frågor genom att ta bort sorteringsoperatorn i exekveringsplanen

Först bör du verifiera att sorten faktiskt är en prestandaflaskhals. Varaktigheten av sorteringen kommer att bero på antalet element som ska sorteras, och antalet butiker för en viss moderbutik är sannolikt litet. (Detta förutsätter att sorteringsoperatorn tillämpas efter tillämpning av where-satsen).

Det är en övergeneralisering. Ofta kan en sorteringsoperator trivialt flyttas in i indexet, och om bara de första par raderna i resultatuppsättningen hämtas, kan det avsevärt minska frågekostnaden, eftersom databasen inte längre behöver hämta alla matchande rader (och sortera dem) alla) för att hitta de första, men kan läsa posterna i resultatuppsättningsordning och stoppa när tillräckligt många poster har hittats.

I ditt fall verkar du hämta hela resultatuppsättningen, så sortering som kommer sannolikt inte att göra saken mycket värre (om inte resultatuppsättningen är enorm). I ditt fall kanske det inte heller är trivialt att bygga ett användbart sorterat index, eftersom where-satsen innehåller ett eller.

Nu, om du fortfarande vill bli av med den sorteringsoperatören, kan du prova:

SELECT [Phone]
FROM [dbo].[Store]
WHERE [ParentStoreId] = 10
AND [Type] in (0, 1)
ORDER BY [Phone]    

Alternativt kan du prova följande index:

CREATE NONCLUSTERED INDEX IX_Store ON dbo.[Store]([ParentStoreId], [Phone], [Type])

för att försöka få frågeoptimeraren att göra en skanning av indexintervall på ParentStoreId bara, skanna sedan alla matchande rader i indexet och mata ut dem om Type tändstickor. Men detta kommer sannolikt att orsaka mer disk I/O och därför sakta ner din fråga snarare än att påskynda den.

Redigera :Som en sista utväg kan du använda

SELECT [Phone]
FROM [dbo].[Store]
WHERE [ParentStoreId] = 10
AND [Type] = 0
ORDER BY [Phone]

UNION ALL

SELECT [Phone]
FROM [dbo].[Store]
WHERE [ParentStoreId] = 10
AND [Type] = 1
ORDER BY [Phone]

med

CREATE NONCLUSTERED INDEX IX_Store ON dbo.[Store]([ParentStoreId], [Type], [Phone])

och sortera de två listorna på applikationsservern, där du kan slå samman (som i merge sort) de försorterade listorna och därmed undvika en fullständig sortering. Men det är verkligen en mikrooptimering som, även om den påskyndar själva sorteringen med en storleksordning, sannolikt inte kommer att påverka den totala exekveringstiden för frågan särskilt mycket, eftersom jag förväntar mig att flaskhalsen är nätverk och disk I/O, speciellt i ljuset av det faktum att disken kommer att göra mycket slumpmässig åtkomst eftersom indexet inte är klustrat.




  1. Codeigniter Active Record - Räkna totalt antal hittade rader med gräns (MySQL)

  2. Oracle 'INSERT ALL' ignorerar dubbletter

  3. VISA TABELLER i MariaDB

  4. Returnera Pandas dataram från PostgreSQL-fråga med sqlalchemy