TSQL Dlaczego Top jest szybszy ze zmienną?

10

Dzień dobry wszystkim,

Pracowałem nad jakimś umiarkowanie złożonym sql, aby „uzyskać” niektóre dane z bazy danych produktów stron trzecich, aby wyświetlić je we własnych aplikacjach wewnętrznych.

Dodałem w zaznaczeniu, aby uzyskać najwyższy rekord z tabeli w podzapytaniu (jeśli to ma sens)

kwerenda zajęła prawie 3 minuty, aby użyć końcowego zestawu wyników 100 rekordów

SELECT TOP 1 ...

Szukałem w Internecie ulepszeń tego, co próbowałem osiągnąć, i zasugerowano, żebym zmienił mój wybór, aby użyć zmiennej, jak poniżej

DECLARE @topCount INT
SET @topCount = 1

SELECT TOP (@topCount) ...

To zajęło to samo zapytanie od 3 minut do 1 sekundy, co jest świetne!

Ale czy ktoś może wyjaśnić, dlaczego tak jest.

JamesStuddart
źródło

Odpowiedzi:

14

Gdy to zrobisz, top 1optymalizator zapytań zbuduje plan, który jest zbudowany tak, aby jak najszybciej pobrać 1 wiersz.

Gdy używasz zmiennej lokalnej, wartość zmiennej jest nieznana optymalizatorowi i zamiast tego tworzy plan zoptymalizowany tak, aby pobrać 100 wierszy tak szybko, jak to możliwe.

W twoim przypadku plan zapytań wygenerowany z celem rzędu 100 jest lepszym planem do użycia, nawet jeśli potrzebujesz tylko jednego wiersza.

Aby to sprawdzić, możesz spróbować dodać option (recompile)do zapytania za pomocą zmiennej. W takim przypadku SQL Server użyje bieżącej wartości @topCountjako celu wiersza, a ponieważ jest to 1, powinieneś otrzymać plan powolny.

Mikael Eriksson
źródło
Rozumiem różnicę w planie, ale dziwi mnie, że pobranie 1 wiersza może być wolniejsze niż pobranie 100 wierszy. Myślę, że jeśli plan 100-wierszowy działa najlepiej, SQL Server użyłby tego samego planu top 1.
Brandon,
@Brandon nie pobiera 100 wierszy, buduje tylko plan wykonania z założeniem, że pożądane jest 100 wierszy. Wykonanie kończy się, gdy zostanie znaleziony 1 wiersz.
Mikael Eriksson,
Sprawdzenie, co różni się od planu wykonania w tych przypadkach, prawdopodobnie pomogłoby zrozumieć, na czym polega problem z pierwszą pozycją.
James Z