Jestem tylko ciekawy, dlaczego zapytanie zagregowane działa o wiele szybciej z GROUP BY
klauzulą niż bez niej.
Na przykład uruchomienie tego zapytania zajmuje prawie 10 sekund
SELECT MIN(CreatedDate)
FROM MyTable
WHERE SomeIndexedValue = 1
Podczas gdy ten zajmuje mniej niż sekundę
SELECT MIN(CreatedDate)
FROM MyTable
WHERE SomeIndexedValue = 1
GROUP BY CreatedDate
W CreatedDate
tym przypadku jest tylko jeden , więc zgrupowane zapytanie zwraca te same wyniki, co zgrupowane.
Zauważyłem, że plany wykonania dwóch zapytań są różne - drugie zapytanie korzysta z równoległości, a pierwsze nie.
Czy to normalne, że SQL Server inaczej ocenia zapytanie zagregowane, jeśli nie ma klauzuli GROUP BY? Czy jest coś, co mogę zrobić, aby poprawić wydajność pierwszego zapytania bez użycia GROUP BY
klauzuli?
Edytować
Właśnie się nauczyłem, że mogę OPTION(querytraceon 8649)
ustawić narzut kosztów równoległości na 0, co sprawia, że zapytanie korzysta z pewnej równoległości i skraca czas działania do 2 sekund, chociaż nie wiem, czy jest jakaś wada korzystania z tej wskazówki zapytania.
SELECT MIN(CreatedDate)
FROM MyTable
WHERE SomeIndexedValue = 1
OPTION(querytraceon 8649)
Wciąż wolę krótszy czas wykonywania, ponieważ zapytanie ma wypełniać wartość po wybraniu użytkownika, więc idealnie powinno być natychmiastowe, tak jak zapytanie zgrupowane. W tej chwili właśnie kończę moje zapytanie, ale wiem, że to nie jest idealne rozwiązanie.
SELECT Min(CreatedDate)
FROM
(
SELECT Min(CreatedDate) as CreatedDate
FROM MyTable WITH (NOLOCK)
WHERE SomeIndexedValue = 1
GROUP BY CreatedDate
) as T
Edytuj # 2
W odpowiedzi na prośbę Martina o dodatkowe informacje :
Zarówno CreatedDate
i SomeIndexedValue
mają oddzielny non-unikalny, nieklastrowanym indeks na nich. SomeIndexedValue
jest właściwie polem varchar (7), mimo że przechowuje wartość liczbową wskazującą na PK (int) innej tabeli. Relacja między dwiema tabelami nie jest zdefiniowana w bazie danych. Nie mam w ogóle zmieniać bazy danych i mogę pisać tylko zapytania, które wyszukują dane.
MyTable
zawiera ponad 3 miliony rekordów, a do każdego rekordu przypisana jest grupa, do której należy ( SomeIndexedValue
). Grupy mogą mieć od 1 do 200 000 rekordów
MAXDOP
ustawia maksymalny stopień równoległości, który ogranicza liczbę procesorów, których może użyć zapytanie. Zasadniczo spowodowałoby to, że drugie zapytanie działałoby tak wolno, jak pierwsze, ponieważ usuwa ono możliwości korzystania z równoległości, czego nie chcę.