Właśnie zacząłem szukać optymalizacji moich zapytań poprzez indeksy, ponieważ dane SQL rosną szybko i szybko. Sprawdziłem, jak optymalizator przetwarza moje zapytanie za pomocą planu wykonania w SSMS i zauważyłem, że jest używany operator sortowania. Słyszałem, że operator Sortuj wskazuje na zły projekt w zapytaniu, ponieważ sortowanie może zostać przedwcześnie zakończone przez indeks. Więc tutaj jest przykład stół i dane podobny do tego, co robię:Optymalizowanie zapytań SQL przez usunięcie operatora sortowania w planie wykonania
IF OBJECT_ID('dbo.Store') IS NOT NULL DROP TABLE dbo.[Store]
GO
CREATE TABLE dbo.[Store]
(
[StoreId] int NOT NULL IDENTITY (1, 1),
[ParentStoreId] int NULL,
[Type] int NULL,
[Phone] char(10) NULL,
PRIMARY KEY ([StoreId])
)
INSERT INTO dbo.[Store] ([ParentStoreId], [Type], [Phone]) VALUES (10, 0, '2223334444')
INSERT INTO dbo.[Store] ([ParentStoreId], [Type], [Phone]) VALUES (10, 0, '3334445555')
INSERT INTO dbo.[Store] ([ParentStoreId], [Type], [Phone]) VALUES (10, 1, '0001112222')
INSERT INTO dbo.[Store] ([ParentStoreId], [Type], [Phone]) VALUES (10, 1, '1112223333')
GO
Oto przykład zapytania:
SELECT [Phone]
FROM [dbo].[Store]
WHERE [ParentStoreId] = 10
AND ([Type] = 0 OR [Type] = 1)
ORDER BY [Phone]
utworzyć non indeksu klastrowego, aby pomóc przyspieszyć zapytanie:
CREATE NONCLUSTERED INDEX IX_Store ON dbo.[Store]([ParentStoreId], [Type], [Phone])
Aby zbudować indeks IX_Store, zacznę z prostych orzeczników
[ParentStoreId] = 10
AND ([Type] = 0 OR [Type] = 1)
Potem dodać kolumnę [Phone]
dla ORDER BY oraz pokrycie OUTPUT Należy wybrać
Więc nawet, gdy indeks jest zbudowany, optymalizator nadal używa operatora Sort (a nie rodzaj indeksu), ponieważ [Phone]
jest posortowana PO [ParentStoreId]
AND [Type]
. Jeśli usunąć kolumnę z indeksu [Type]
i uruchomić kwerendę:
SELECT [Phone]
FROM [dbo].[Store]
WHERE [ParentStoreId] = 10
--AND ([Type] = 0 OR [Type] = 1)
ORDER BY [Phone]
Wtedy oczywiście operator Sortowanie nie jest używany przez optymalizator ponieważ [Phone]
jest posortowana według [ParentStoreId]
.
Pytanie więc, w jaki sposób mogę utworzyć indeks, który obejmie kwerendę (w tym predykat [Type]
) i czy optymalizator nie użyje sortowania?
EDIT:
tabela pracuję z ponad 20 milionów wierszy
Naprawdę powinieneś uczynić '[StoreId]' kluczem podstawowym (który również domyślnie klastruje przy okazji), a nie tylko dodać unikalny indeks. – Lucero
Możesz być w stanie obejść ten problem, tworząc * drugi * indeks w kolumnie Telefon. –
@ Lucero, zmodyfikowałem swój post, aby zaznaczyć '[StoreId]' jako klucz podstawowy, chociaż nie sądzę, że rozwiąże to problem sortowania – jodev