Są sytuacje, które wymagają naprawdę dużego zapytania łączącego kilka tabel razem z instrukcjami sub select w celu uzyskania pożądanych rezultatów.
Moje pytanie brzmi: czy powinniśmy rozważyć użycie wielu mniejszych zapytań i przenieść operacje logiczne do warstwy aplikacji, wysyłając zapytanie do bazy danych w więcej niż jednym wywołaniu, czy lepiej mieć je wszystkie za jednym razem?
Na przykład rozważ następujące zapytanie:
SELECT *
FROM `users`
WHERE `user_id` IN (SELECT f2.`friend_user_id`
FROM `friends` AS f1
INNER JOIN `friends` AS f2
ON f1.`friend_user_id` = f2.`user_id`
WHERE f2.`is_page` = 0
AND f1.`user_id` = "%1$d"
AND f2.`friend_user_id` != "%1$d"
AND f2.`friend_user_id` NOT IN (SELECT `friend_user_id`
FROM `friends`
WHERE `user_id` = "%1$d"))
AND `user_id` NOT IN (SELECT `user_id`
FROM `friend_requests`
WHERE `friend_user_id` = "%1$d")
AND `user_image` IS NOT NULL
ORDER BY RAND()
LIMIT %2$d
Jak najlepiej to zrobić?
źródło
Jako ktoś, kto musi wspierać / oczyszczać te duże i skomplikowane zapytania, powiedziałbym, że o wiele lepiej jest podzielić je na kilka małych, łatwych do zrozumienia części. Z punktu widzenia wydajności niekoniecznie jest to lepsze, ale przynajmniej dajesz SQLowi większą szansę na wymyślenie dobrego planu zapytań.
Ułatw życie ludziom, którzy podążają za tobą, a będą mówić o tobie dobre rzeczy. Uciskaj ich, a przeklną cię.
źródło
Moje 2 centy za 2 słowa kluczowe wydajność zapytania i skalowalność:
Wydajność zapytań: Równoległość programu SQL Server wykonuje już bardzo dobrą robotę, dzieląc zapytania na wyszukiwania wielowątkowe, więc nie jestem pewien, ile ulepszenia wydajności zapytań zobaczysz, robiąc to dla programu SQL Server. Będziesz musiał spojrzeć na plan wykonania, aby zobaczyć, jaki stopień równoległości uzyskujesz, gdy go wykonasz, i porównać wyniki w obie strony. Jeśli w końcu będziesz musiał użyć wskazówki zapytania, aby uzyskać taką samą lub lepszą wydajność, wtedy IMO nie jest tego warte, ponieważ wskazówka zapytania może nie być optymalna później.
Skalowalność: czytanie zapytań może być łatwiejsze, jak stwierdził datagod, a podział na osobne zapytania ma sens, jeśli możesz używać nowych zapytań również w innych obszarach, ale jeśli nie zamierzasz ich używać również do innych połączeń, będzie jeszcze więcej przechowywanych procesów do zarządzania dla jednego zadania, a IMO nie przyczyni się do skalowalności.
źródło
LIMIT
Czasami nie ma innego wyjścia, jak podzielić duże / złożone zapytanie na małe zapytania. Najlepszym sposobem ustalenia tego byłoby użycie
EXPLAIN
instrukcji zSELECT
instrukcją. Liczba śladów / skanów, które wykona db w celu pobrania danych, jest iloczynem wartości „wierszy” zwróconych przezEXPLAIN
zapytanie. W naszym przypadku mieliśmy zapytanie łączące 10 tabel. Dla konkretnego rekordu ślad wyniósł 409 mln blogów na naszej bazie danych i zwiększył wykorzystanie procesora na naszym serwerze DB o ponad 300%. Byliśmy w stanie odzyskać te same informacje, dzieląc zapytania znacznie szybciej.Krótko mówiąc, w niektórych przypadkach rozdzielenie złożonego / dużego zapytania ma sens, ale w innych może prowadzić do wielu problemów z wydajnością lub utrzymaniem i należy to rozpatrywać indywidualnie.
źródło