2010-05-13 7 views
5

Staramy się zoptymalizować niektóre z naszych zapytań.Dlaczego użycie tabeli tymczasowej będzie szybsze niż zapytanie zagnieżdżone?

Jedno zapytanie jest w następujący sposób:

SELECT t.TaskID, t.Name as Task, '' as Tracker, t.ClientID, (<complex subquery>) Date, 
INTO [#Gadget] 
FROM task t 

SELECT TOP 500 TaskID, Task, Tracker, ClientID, dbo.GetClientDisplayName(ClientID) as Client 
FROM [#Gadget] 
order by CASE WHEN Date IS NULL THEN 1 ELSE 0 END , Date ASC 

DROP TABLE [#Gadget] 

(usunąłem złożoną podzapytanie nie sądzę, że to istotne, inne niż wyjaśnić dlaczego ta kwerenda została wykonana jako proces dwustopniowy.).

I myślał byłoby znacznie bardziej efektywne, aby połączyć to w dół w jednym zapytaniu za pomocą podzapytania jako:

SELECT TOP 500 TaskID, Task, Tracker, ClientID, dbo.GetClientDisplayName(ClientID) 
FROM 
(
    SELECT t.TaskID, t.Name as Task, '' as Tracker, t.ClientID, (<complex subquery>) Date, 
    FROM task t 
) as sub  
order by CASE WHEN Date IS NULL THEN 1 ELSE 0 END , Date ASC 

Zapewni to optymalizatorowi lepsze informacje, aby ustalić, co się dzieje i uniknąć tabel tymczasowych. Zakładałem, że powinno być szybciej.

Ale okazuje się, że jest o wiele wolniej. 8 sekund vs. poniżej 5 sekund.

Nie mogę zrozumieć, dlaczego tak się stało, ponieważ cała moja wiedza na temat baz danych oznacza, że ​​podzapytania zawsze będą szybsze niż używanie tabel tymczasowych.

Czego mi brakuje?

Edit -

Z tego co udało mi się zobaczyć z planów zapytań, oba są w dużej mierze identyczne, z wyjątkiem tabeli tymczasowej, która ma dodatkowy „Tabela Wstaw” działanie z kosztem 18 %.

Oczywiście, ponieważ ma dwa zapytania, koszt Sort Top N jest o wiele wyższy w drugim zapytaniu niż koszt sortowania w metodzie podzapytania, więc trudno jest dokonać bezpośredniego porównania kosztów.

Wszystko, co widzę z planów, oznaczałoby, że metoda podzapytania byłaby szybsza.

+2

Czy porównywałeś plany kwerend? – Oded

+0

@Oded, zobacz moją edycję. –

+0

Czy wyczyściłeś pamięć podręczną danych między poszczególnymi testami? Jeśli nie, to może skończyć się twoim porównaniem – AdaTheDev

Odpowiedz

3

Oczywiście SQL Server wybiera zły plan kwerend. Tak, to może się zdarzyć, miałem dokładnie taki sam scenariusz jak ty kilka razy.

Problem polega na tym, że optymalizacja zapytania (wspominasz o "złożonym podzapytaniu") jest nietrywialnym zadaniem: jeśli masz n tabel, jest ich mniej więcej n! możliwe przyłączyć zamówienia - i to dopiero początek. Jest więc całkiem prawdopodobne, że wykonanie (a) najpierw wewnętrznej kwerendy i (b), a następnie zewnętrznego zapytania jest dobrym sposobem, aby przejść, ale SQL Server nie może wydedukować tych informacji w rozsądnym czasie.

Co można zrobić, aby pomóc SQL Server. Jak pisze Dan Tow w swojej świetnej książce "SQL Tuning", kluczem jest zazwyczaj kolejność łączenia, od najbardziej selektywnego do najmniej selektywnego.Używając zdrowego rozsądku (lub metody opisanej w jego książce, która jest o wiele lepsza), możesz określić, która kolejność łączenia będzie najbardziej odpowiednia, a następnie użyć wskazówki dotyczącej zapytania FORCE ORDER.

W każdym razie każde zapytanie jest unikalne, nie ma "magicznego przycisku", aby serwer SQL był szybszy. Jeśli naprawdę chcesz się dowiedzieć, co się dzieje, musisz spojrzeć na (lub pokazać) plany zapytań swoich zapytań. Inne interesujące dane pokazują SET STATISTICS IO, które pokażą, ile (kosztownego) dostępu HDD generuje twoje zapytanie.

4

"Powinno być" to niebezpieczna rzecz powiedzieć o wydajności bazy danych. Często stwierdzam, że tabele tymczasowe przyspieszają, czasem dramatycznie. Proste wyjaśnienie polega na tym, że ułatwia to optymalizatorowi uniknięcie powtarzania pracy.

Oczywiście widziałem również tabele tymczasowe, które spowalniają działanie, a czasami są znacznie wolniejsze.

Nie ma możliwości zastąpienia profilowania i studiowania planów kwerend (mimo to odczytaj ich prognozy z przymrużeniem oka).

0

I potwierdził to pytanie tutaj: How can I force a subquery to perform as well as a #temp table?

Istotę to jest, tak, rozumiem, że czasami optymalizator jest prawo do wtrącania się ze swoimi podzapytaniami jak gdyby nie były one w pełni autonomiczny, ale czasami robi zły zła kolej, gdy próbuje być sprytna w sposób, który wszyscy znamy. Twierdzę, że musi istnieć sposób wyłączenia tej "sprytności" tam, gdzie jest to konieczne, zamiast niszczyć podejście oparte na widoku z tabelami tymczasowymi.

+0

Tylko do aktualizacji. Martin Smith dostarczył odpowiedź, która zadziałała dla mnie, wskazując tutaj: http://connect.microsoft.com/SQLServer/feedback/details/218968/ Prawdopodobnie naprawił problem tego pytającego, chociaż Martin zwrócił uwagę, że szpula nie mają statystyki takie jak tabele tymczasowe i jest to hack, który wymaga ORDER BY, które może ponieść rzeczywisty koszt dla niektórych. – Adamantish

Powiązane problemy