Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Optymalizacja zapytań SQL poprzez usunięcie operatora Sort w Planie wykonania

Najpierw należy sprawdzić, czy sortowanie jest w rzeczywistości wąskim gardłem wydajności. Czas trwania sortowania będzie zależał od liczby elementów do posortowania, a liczba sklepów dla konkretnego sklepu nadrzędnego prawdopodobnie będzie niewielka. (To jest przy założeniu, że operator sortowania jest stosowany po zastosowaniu klauzuli where).

To nadmierna generalizacja. Często operator sortowania może być w prosty sposób przeniesiony do indeksu, a jeśli tylko pierwszych kilka wierszy zbioru wyników zostanie pobranych, może znacznie obniżyć koszt zapytania, ponieważ baza danych nie musi już pobierać wszystkich pasujących wierszy (i sortować ich wszystkie), aby znaleźć pierwsze, ale może odczytać rekordy w kolejności zestawu wyników i zatrzymać się, gdy zostanie znaleziona wystarczająca liczba rekordów.

W twoim przypadku wydaje się, że pobierasz cały zestaw wyników, więc sortowanie, które prawdopodobnie nie pogorszy sytuacji (chyba że zestaw wyników jest ogromny). Również w twoim przypadku zbudowanie użytecznego posortowanego indeksu może nie być trywialne, ponieważ klauzula where zawiera lub.

Teraz, jeśli nadal chcesz pozbyć się tego operatora sortującego, możesz spróbować:

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

Możesz też wypróbować następujący indeks:

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

aby spróbować uzyskać optymalizator zapytań, aby wykonał skanowanie zakresu indeksów na ParentStoreId tylko, a następnie przeskanuj wszystkie pasujące wiersze w indeksie, wyświetlając je, jeśli Type mecze. Jednak może to spowodować więcej operacji we/wy na dysku, a tym samym spowolnić zapytanie, a nie je przyspieszyć.

Edytuj :W ostateczności możesz użyć

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]

z

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

i posortować dwie listy na serwerze aplikacji, gdzie można scalić (jak w sortowaniu przez scalanie) wstępnie posortowane listy, unikając w ten sposób pełnego sortowania. Ale to naprawdę mikrooptymalizacja, która, przyspieszając samo sortowanie o rząd wielkości, prawdopodobnie nie wpłynie znacząco na całkowity czas wykonania zapytania, ponieważ spodziewałbym się, że wąskie gardło będzie we/wy sieci i dysku, zwłaszcza w świetle faktu, że dysk będzie miał dużo losowego dostępu, ponieważ indeks nie jest klastrowany.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. OPENROWSET nie akceptuje zmiennych dla swoich argumentów (SQL Server)

  2. Kosztorysowanie zapasów według metody FIFO

  3. Wybierz oświadczenie, aby znaleźć duplikaty w określonych polach

  4. SQL Server uruchamiający monitorowanie zapytań

  5. Jak złapać wyjątki limitu czasu SQLServer?