Dlaczego istnieje ogromna różnica w wydajności między tabelą tymczasową a zaznaczeniem podrzędnym

To jest pytanie o SQL Server 2008 R2

Nie jestem DBA, jak na razie. Jestem programistą Javy, który od czasu do czasu musi pisać SQL. (głównie osadzone w kodzie). Chcę wiedzieć, czy zrobiłem tu coś złego, a jeśli tak, to co mogę zrobić, aby to się nie powtórzyło.

Q1:

SELECT something FROM (SELECT * FROM T1 WHERE condition1) JOIN ...

Q1 zawiera 14 połączeń

Q2 jest tym samym co Q1, z jednym wyjątkiem. (SELECT * FROM T1 WHERE condition1) jest wykonywane przed i przechowywane w tabeli temp.

To nie jest skorelowane zapytanie podrzędne.

Q2:

SELECT * INTO #tempTable FROM T1 WHERE condition1
SELECT something FROM #tempTable  JOIN ...
/ Align = "left" /

To, co mnie teraz zastanawia, to to, że Q1 zajęło > 2min, (próbowałem kilka razy, aby uniknąć buforowania, aby odegrać rolę), podczas gdy Q2 (oba zapytania połączone) zajęło 2sec!!! Co jest?

Author: Arvand, 2013-05-27

2 answers

Dlaczego nie zaleca się używania zapytań podrzędnych?

Database Optimizer (niezależnie od tego, jakiej bazy danych używasz) nie zawsze może poprawnie zoptymalizować takie zapytanie (z zapytaniami podrzędnymi). W takim przypadku problemem optymalizatora jest wybór odpowiedniego sposobu łączenia zestawów wyników. Istnieje kilka algorytmów łączenia dwóch zestawów wyników. Wybór algorytmu zależy od liczby rekordów zawartych w jednym i w drugim zbiorze wyników. W przypadku połączenia dwóch tabel fizycznych (subquery nie jest tabelą fizyczną), baza danych może łatwo określić ilość danych w dwóch zestawach wyników za pomocą dostępnych statystyk. Jeśli jeden z zestawów wyników jest zapytaniem podrzędnym, to zrozumienie, ile rekordów zwraca, jest bardzo trudne. W tym przypadku baza danych może wybrać niewłaściwy Plan zapytania połączenia, co doprowadzi do znacznego zmniejszenia wydajności zapytania.

Przepisanie zapytania za pomocą tabel tymczasowych ma na celu uproszczenie optymalizacji bazy danych. W przepisane zapytanie wszystkie zestawy wyników biorące udział w połączeniach będą fizycznymi tabelami, a baza danych z łatwością określi długość każdego zestawu wyników. Pozwoli to bazie danych wybrać gwarantowany najszybszy ze wszystkich możliwych planów zapytań. Ponadto baza danych dokona właściwego wyboru bez względu na warunki. Przepisane zapytanie z tabelami tymczasowymi sprawdziłoby się dobrze w każdej bazie danych, jest to szczególnie ważne w rozwoju przenośnych rozwiązań. Ponadto przepisany zapytanie jest łatwiejsze do odczytania, łatwiejsze do zrozumienia i do debugowania.

Zrozumiałe jest, że przepisanie zapytania tabelami tymczasowymi może spowodować pewne spowolnienie z powodu dodatkowych kosztów: tworzenie tabel tymczasowych. Jeśli baza danych nie pomyli się z wyborem planu zapytań, wykona stare zapytanie szybciej niż nowe. Jednak to spowolnienie zawsze będzie znikome. Zazwyczaj tworzenie tymczasowej tabeli zajmuje kilka milisekund. Oznacza to, że opóźnienie nie może mieć znaczący wpływ na wydajność systemu i zwykle można go zignorować.

Ważne! Nie zapomnij utworzyć indeksów dla tabel tymczasowych. Pola indeksu powinny zawierać wszystkie pola używane w Warunkach łączenia.

 42
Author: Karthik AMR,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-27 09:26:44

Jest tu wiele rzeczy do rozwiązania, indeksy, plany realizacji itp. Testowanie i porównywanie wyników jest drogą do zrobienia.

Możesz przyjrzeć się zwykłym podejrzanym, indeksom. Przyjrzyj się planowi egzekucji i porównaj je. Upewnij się, że klauzula WHERE używa poprawnych. Upewnij się, że używasz indeksów JOINs. Te odpowiedzi na pewno bardzo ci pomogą.
 8
Author: Yaroslav,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:54:59