Kiedy używać zapytań podrzędnych SQL a standard join?

Pracuję nad przepisaniem źle napisanych zapytań SQL i są one nadmiernie wykorzystujące zapytania podrzędne. Szukam najlepszych praktyk w zakresie korzystania z zapytań podrzędnych.

Każda pomoc będzie mile widziana.

Author: Brad Krusemark, 2011-01-26

3 answers

Subqueries są zwykle w porządku, chyba że są subqueries zależne (znane również jako subqueries skorelowane ). Jeśli używasz tylko niezależnych zapytań podrzędnych i używają odpowiednich indeksów, powinny one działać szybko. Jeśli masz zapytanie podrzędne zależne, możesz napotkać problemy z wydajnością, ponieważ zapytanie podrzędne zazwyczaj musi być uruchomione raz dla każdego wiersza zapytania zewnętrznego. Więc jeśli twoje zewnętrzne zapytanie ma 1000 wierszy, zapytanie podrzędne zostanie uruchomione 1000 razy. Z drugiej strony podaj niezależne zapytanie podrzędne zwykle musi być ocenione tylko raz.

Jeśli nie jesteś pewien, co oznacza subquery zależne lub niezależne, oto zasada - jeśli możesz wziąć subquery, usunąć je z kontekstu, uruchomić i uzyskać zestaw wyników, to jest to independent subquery.

Jeśli pojawi się błąd składni, ponieważ odnosi się on do niektórych tabel poza zapytaniem podrzędnym, to jest to dependent subquery.

Ogólna zasada ma oczywiście kilka wyjątków. Na przykład:

  • wiele optymalizatorów może pobierać zależne zapytania podrzędne i znaleźć sposób na wydajne uruchamianie ich jako JOIN. Na przykład zapytanie nie istnieje może skutkować planem zapytań anty JOIN, więc niekoniecznie będzie wolniejsze niż pisanie zapytania za pomocą JOIN.
  • MySQL ma błąd , w którym niezależne zapytanie wewnątrz wyrażenia IN jest nieprawidłowo identyfikowane jako zapytanie zależne i dlatego używany jest nieoptymalny Plan zapytań. Jest to najwyraźniej naprawione w najnowszym wersje MySQL.

Jeśli wydajność jest problemem, Zmierz swoje konkretne zapytania i zobacz, co działa najlepiej dla Ciebie.

 44
Author: Mark Byers,
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
2011-09-20 18:56:32

Nie ma tu srebrnej kuli. Każde użycie musi być niezależnie ocenione. Istnieją przypadki, w których skorelowane zapytania podrzędne są po prostu nieefektywne, ten poniżej jest lepiej napisany jako JOIN

select nickname, (select top 1 votedate from votes where user_id=u.id order by 1 desc)
from users u

Z drugiej strony zapytania EXISTS I NOT EXISTS wygrywają przez JOINs.

select ...
where NOT EXISTS (.....)

Jest zwykle szybszy niż

select ...
FROM A LEFT JOIN B
where B.ID is null
Jednak nawet te uogólnienia mogą być nieprawdziwe dla każdego konkretnego schematu i rozkładu danych.
 6
Author: RichardTheKiwi,
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
2011-01-25 23:07:02

Niestety odpowiedź w dużym stopniu zależy od używanego serwera sql. W teorii połączenia są lepsze z czysto relacyjnego punktu widzenia teorii. Pozwalają serwerowi zrobić właściwą rzecz pod maską i dają im większą kontrolę, a tym samym w końcu mogą być szybsze. Jeśli serwer jest dobrze zaimplementowany. W praktyce niektóre serwery SQL działają lepiej, jeśli oszukasz go w celu optymalizacji zapytań za pomocą zapytań podrzędnych i tym podobnych.

 4
Author: Wes Hardaker,
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
2011-01-25 23:02:44