JOIN zapytania a wiele zapytań

180

Czy zapytania JOIN są szybsze niż kilka zapytań? (Uruchamiasz swoje główne zapytanie, a następnie uruchamiasz wiele innych poleceń SELECT w oparciu o wyniki Twojego głównego zapytania)

Pytam, ponieważ DOŁĄCZENIE ich bardzo skomplikowałoby projekt mojej aplikacji

Jeśli są szybsze, czy ktoś może z grubsza oszacować, o ile? Jeśli jest 1,5x, nie obchodzi mnie to, ale jeśli jest 10x, chyba tak.

Thomas Bonini
źródło
Zakładam, że byliby szybsi. Wiem, że jeden INSERT w porównaniu do 10 indywidualnych zapytań INSERT jest znacznie szybszy.
Alex
1
Może być ważne, czy Twoje wiele zapytań znajduje się w procedurze składowanej lub czy pochodzą z aplikacji (edytuj swoje pytanie z tymi informacjami). Ten pierwszy będzie znacznie szybszy niż później.
kolithium
dba.stackexchange.com/questions/42998/…
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Odpowiedzi:

82

Jest to zbyt niejasne, aby dać ci odpowiedź odpowiednią dla twojego konkretnego przypadku. To zależy od wielu rzeczy. Pisał o tym Jeff Atwood (założyciel tej strony) . Jednak w przeważającej części, jeśli masz odpowiednie indeksy i poprawnie wykonujesz JOIN, zwykle będzie to szybsze wykonanie 1 podróży niż kilku.

Paolo Bergantino
źródło
2
jeśli łączysz 3 lub więcej tabel na różnych kluczach, często bazy danych (np. mysql) mogą używać tylko jednego indeksu na tabelę, co oznacza, że ​​może jedno z połączeń będzie szybkie (i użyje indeksu), podczas gdy inne będą bardzo wolne. W przypadku wielu zapytań można zoptymalizować indeksy, które będą używane dla każdego zapytania.
user151975
4
Myślę, że zależy to od twojej definicji „szybszego” ... na przykład, 3 PK łączenia wewnętrzne mogą obracać się szybciej niż 4 okrążenia, z powodu narzutu sieci i ponieważ musisz zatrzymać i przygotować i wysłać każde zapytanie po poprzednie zapytanie zostało zakończone. Jeśli jednak miałbyś testować serwer pod obciążeniem, w większości przypadków łączenia zajmą więcej czasu procesora niż zapytania PK i często powodują również większe obciążenie sieci.
mindplay.dk
97

W przypadku sprzężeń wewnętrznych jedno zapytanie ma sens, ponieważ otrzymujesz tylko pasujące wiersze. W przypadku złączeń lewostronnych wiele zapytań jest znacznie lepszych ... spójrz na następujący test porównawczy, który zrobiłem:

  1. Pojedyncze zapytanie z 5 połączeniami

    pytanie: 8,074508 sekund

    wielkość wyniku: 2268000

  2. 5 zapytań z rzędu

    połączony czas zapytania: 0,00262 sekundy

    wielkość wyniku: 165 (6 + 50 + 7 + 12 + 90)

.

Zauważ, że otrzymujemy te same wyniki w obu przypadkach (6 x 50 x 7 x 12 x 90 = 2268000)

lewe sprzężenia zajmują wykładniczo więcej pamięci z nadmiarowymi danymi.

Limit pamięci może nie być tak zły, jeśli łączysz tylko dwie tabele, ale generalnie trzy lub więcej i staje się to warte różnych zapytań.

Na marginesie, mój serwer MySQL znajduje się tuż obok mojego serwera aplikacji ... więc czas połączenia jest znikomy. Jeśli czas połączenia jest w sekundach, być może jest to korzystne

Szczery

Frank Forte
źródło
31
Jeśli pominiemy ten irytujący mały fakt, że nikt przy zdrowych zmysłach nie wykonuje łączenia krzyżowego między 5 stołami (z tego właśnie powodu, w większości przypadków po prostu nie ma to sensu ), Twój „punkt odniesienia” może mieć jakąś wartość . Ale łączenia lewe lub wewnętrzne są normą, zwykle za pomocą klucza (dzięki czemu pobieranie jest znacznie szybsze), a duplikacja danych jest zwykle znacznie, dużo mniejsza, niż się wydaje.
cHao
12
@cHao mówi kto? Właśnie wyszukałem SMF i phpBB i zobaczyłem JOIN między trzema tabelami - jeśli dodasz wtyczki lub modyfikacje, można je łatwo dodać. Każda duża aplikacja ma potencjał dla wielu POŁĄCZEŃ. Prawdopodobnie źle napisany / źle użyty ORM mógłby DOŁĄCZYĆ tabele, których w rzeczywistości nie potrzebuje (być może nawet każdą tabelę).
Natalie Adams
5
@NathanAdams: Lewe i wewnętrzne łączenia nie są wcale złe. (W rzeczywistości, jeśli nie dołączasz do tabel tu i tam, robisz błąd SQL.) To, o czym mówiłem, to łączenia krzyżowe , które są prawie zawsze niepożądane nawet między dwiema tabelami, nie mówiąc już o 5 - i które być jedynym sposobem na uzyskanie wspomnianych powyżej całkowicie fałszywych wyników „2268000”.
cHao
2
Spójrz jednak na wyniki. „rozmiar wyniku: 2268000” a „rozmiar wyniku: 165”. Myślę, że twoje spowolnienie z JOINs wynika z tego, że twoje płyty mają ze sobą relację jeden do wielu, podczas gdy gdyby miały relację jeden do jednego, JOIN byłby zdecydowanie szybszy i na pewno nie miałby wyniku rozmiar większy niż SELECT.
HoldOffHunger
3
@cHao Oczywiście nie spotkałeś Magento w momencie, gdy
pisałeś
26

To pytanie jest stare, ale brakuje niektórych testów. Porównałem JOIN z jego 2 konkurentami:

  • N + 1 zapytań
  • 2 zapytania, drugie z użyciem WHERE IN(...)lub odpowiednika

Wynik jest jasny: na MySQL JOINjest znacznie szybszy. Zapytania N + 1 mogą drastycznie obniżyć wydajność aplikacji:

JOIN vs WHERE IN vs N + 1

To znaczy, chyba że wybierzesz wiele rekordów, które wskazują na bardzo małą liczbę odrębnych, zagranicznych rekordów. Oto punkt odniesienia dla skrajnego przypadku:

JOIN vs N + 1 - wszystkie rekordy wskazujące na ten sam rekord zagraniczny

Jest to bardzo mało prawdopodobne w typowej aplikacji, chyba że łączysz się z relacją -to-many, w którym to przypadku klucz obcy znajduje się w drugiej tabeli i wielokrotnie kopiujesz dane z tabeli głównej.

Na wynos:

  • W przypadku relacji * -to-jeden zawsze używaj JOIN
  • W przypadku relacji * do wielu drugie zapytanie może być szybsze

Zobacz mój artykuł na Medium, aby uzyskać więcej informacji.

Benzoes
źródło
22

Właściwie to sam doszedłem do tego pytania szukając odpowiedzi, a po przeczytaniu udzielonych odpowiedzi mogę się tylko zgodzić, że najlepszym sposobem porównania wydajności zapytań DB jest uzyskanie rzeczywistych liczb, ponieważ jest zbyt wiele zmiennych do wzięcia pod uwagę ALE myślę również, że porównywanie liczb między nimi prowadzi do niczego dobrego w prawie wszystkich przypadkach. Chodzi mi o to, że liczby należy zawsze porównywać z dopuszczalną liczbą i zdecydowanie nie porównywać między sobą.

Rozumiem, że jeśli jeden sposób odpytywania zajmuje powiedzmy 0,02 sekundy, a drugi 20 sekund, to ogromna różnica. Ale co, jeśli jeden sposób wykonywania zapytań zajmuje 0,0000000002 sekundy, a drugi 0,0000002 sekundy? W obu przypadkach jedna droga jest aż 1000 razy szybsza niż druga, ale czy rzeczywiście wciąż „fest” w drugim przypadku?

Podsumowując, jak osobiście to widzę: jeśli działa dobrze, wybierz proste rozwiązanie.

Valentin Flachsel
źródło
4
To oczywiście zależy od tego, czy planujesz skalowanie. Ponieważ kiedy Facebook zaczynał, jestem pewien, że mieli tego rodzaju zapytania, ale myśleli o skalowaniu i wybrali bardziej wydajne, choć być może bardziej złożone rozwiązanie.
dudewad
@dudewad Ma sens. Ostatecznie wszystko zależy od tego, czego potrzebujesz.
Valentin Flachsel,
4
Haha tak ... ponieważ w Google 1 utrata nanosekundy jest dosłownie równa około 10 miliardów bilionów dolarów ... ale to tylko plotka.
dudewad
2
@dudewad Właściwie, kiedy Facebook zaczynał, gwarantuję, że poszedł z prostszym rozwiązaniem. Zuckerberg powiedział, że zaprogramował pierwszą wersję w zaledwie 2 tygodnie. Startupy muszą działać szybko, aby konkurować, a te, które przetrwają, zwykle nie martwią się skalowaniem, dopóki naprawdę tego nie potrzebują. Następnie dokonują refaktoryzacji, gdy mają miliony dolarów inwestycji i mogą zatrudniać programistów rockstar, którzy specjalizują się w wydajności. Do twojego punktu, spodziewałbym się, że Facebook często wybiera teraz bardziej złożone rozwiązanie, aby uzyskać niewielki wzrost wydajności, ale większość z nas nie programuje Facebooka.
dallin
15

Wykonałem szybki test, wybierając jeden wiersz z tabeli zawierającej 50 000 wierszy i łącząc go z jednym wierszem z tabeli zawierającej 100 000 wierszy. Zasadniczo wyglądał tak:

$id = mt_rand(1, 50000);
$row = $db->fetchOne("SELECT * FROM table1 WHERE id = " . $id);
$row = $db->fetchOne("SELECT * FROM table2 WHERE other_id = " . $row['other_id']);

vs

$id = mt_rand(1, 50000);
$db->fetchOne("SELECT table1.*, table2.*
    FROM table1
    LEFT JOIN table1.other_id = table2.other_id
    WHERE table1.id = " . $id);

Dwie metody wyboru zajęły 3,7 sekundy dla 50000 odczytów, podczas gdy JOIN zajęło 2,0 sekundy na moim wolnym komputerze w domu. INNER JOIN i LEFT JOIN nie robiły różnicy. Pobieranie wielu wierszy (np. Przy użyciu IN SET) dało podobne wyniki.

lewany
źródło
1
Może różnica może zmienić się inaczej, jeśli wybierzesz stronę z wierszami (np. 20 lub 50), tak jak w przypadku typowej siatki widoku sieci, i porównasz pojedyncze LEFT JOIN z dwoma zapytaniami - wybranie 2 lub 3 identyfikatorów z niektórymi kryteriami WHERE, a następnie uruchomienie drugiego Zapytanie SELECT z IN ().
JustAMartin
Czy kolumny id i other_id są indeksowane?
Aarish Ramesh
11

Prawdziwe pytanie brzmi: czy te rekordy mają relację jeden do jednego czy jeden do wielu ?

Odpowiedź TLDR:

Jeśli masz jeden do jednego, użyj pliku JOIN instrukcji.

Jeśli jeden do wielu, użyj jednej (lub wielu) SELECTinstrukcji z optymalizacją kodu po stronie serwera.

Dlaczego i jak używać SELECT do optymalizacji

SELECTPraca (z wieloma zapytaniami zamiast łączenia) na dużej grupie rekordów w oparciu o relację jeden do wielu zapewnia optymalną wydajność, ponieważ JOINwiąże się z wykładniczym problemem wycieku pamięci. Pobierz wszystkie dane, a następnie posortuj je za pomocą języka skryptowego po stronie serwera:

SELECT * FROM Address WHERE Personid IN(1,2,3);

Wyniki:

Address.id : 1            // First person and their address
Address.Personid : 1
Address.City : "Boston"

Address.id : 2            // First person's second address
Address.Personid : 1
Address.City : "New York"

Address.id : 3            // Second person's address
Address.Personid : 2
Address.City : "Barcelona"

Tutaj otrzymuję wszystkie rekordy w jednej wybranej instrukcji. Jest to lepsze niż JOINpobieranie niewielkiej grupy tych rekordów, pojedynczo, jako podkomponentu innego zapytania. Następnie analizuję go za pomocą kodu po stronie serwera, który wygląda mniej więcej tak ...

<?php
    foreach($addresses as $address) {
         $persons[$address['Personid']]->Address[] = $address;
    }
?>

Kiedy nie używać JOIN do optymalizacji

JOINTworzenie dużej grupy rekordów w oparciu o relację jeden do jednego z jednym rekordem zapewnia optymalną wydajność w porównaniu z wieloma SELECT instrukcjami, jeden po drugim, które po prostu pobierają następny typ rekordu.

Ale JOIN jest nieefektywny w przypadku uzyskiwania rekordów w relacji jeden do wielu.

Przykład: Baza danych Blogi zawiera 3 interesujące tabele: Post na blogu, Znacznik i Komentarz.

SELECT * from BlogPost
LEFT JOIN Tag ON Tag.BlogPostid = BlogPost.id
LEFT JOIN Comment ON Comment.BlogPostid = BlogPost.id;

Jeśli jest 1 post na blogu, 2 tagi i 2 komentarze, otrzymasz wyniki takie jak:

Row1: tag1, comment1,
Row2: tag1, comment2,
Row3: tag2, comment1,
Row4: tag2, comment2,

Zwróć uwagę, jak każdy rekord jest zduplikowany. OK, więc 2 komentarze i 2 tagi to 4 rzędy. A co jeśli mamy 4 komentarze i 4 tagi? Nie dostajesz 8 rzędów - dostajesz 16 rzędów:

Row1: tag1, comment1,
Row2: tag1, comment2,
Row3: tag1, comment3,
Row4: tag1, comment4,
Row5: tag2, comment1,
Row6: tag2, comment2,
Row7: tag2, comment3,
Row8: tag2, comment4,
Row9: tag3, comment1,
Row10: tag3, comment2,
Row11: tag3, comment3,
Row12: tag3, comment4,
Row13: tag4, comment1,
Row14: tag4, comment2,
Row15: tag4, comment3,
Row16: tag4, comment4,

Dodaj więcej tabel, więcej rekordów itp., A problem szybko rozwinie się do setek wierszy, które są pełne w większości nadmiarowych danych.

Ile kosztują te duplikaty? Pamięć (na serwerze SQL i kod, który próbuje usunąć duplikaty) i zasoby sieciowe (między serwerem SQL a serwerem kodu).

Źródło: https://dev.mysql.com/doc/refman/8.0/en/nested-join-optimization.html ; https://dev.mysql.com/doc/workbench/en/wb-relationship-tools.html

HoldOffHunger
źródło
Nie rozumiesz. Nie chodzi o jeden do (jeden | wielu). Chodzi o to, czy zestawy wierszy mają sens, aby połączyć je w pary. Prosisz o dwa tylko stycznie powiązane zestawy danych. Jeśli prosiłeś o komentarze i, powiedzmy, dane kontaktowe ich autorów, ma to większy sens jako dołączenie, nawet jeśli ludzie mogą przypuszczalnie napisać więcej niż jeden komentarz.
cHao
@cHao: Dziękuję za komentarz. Moja odpowiedź powyżej to podsumowanie dokumentacji MySQL, którą można znaleźć tutaj: dev.mysql.com/doc/workbench/en/wb-relationship-tools.html
HoldOffHunger
To nie jest dokumentacja MySQL. Jest to dokumentacja dla konkretnego narzędzia GUI do pracy z bazami danych MySQL. I nie oferuje żadnych wskazówek, kiedy łączenia są (lub nie są) odpowiednie.
cHao
@cHao: Przepraszam, miałem na myśli dokumentację MySQL (R) dla MySQL WorkBench (TM), a nie MySQL Server (TM).
HoldOffHunger
Pomijając pedanterię, znaczenie nie jest jasne. Obie wspominają o relacjach jeden do jednego i jeden do wielu, ale na tym kończy się wspólność. Tak czy inaczej, problem dotyczy relacji między zbiorami danych. Połącz dwa niepowiązane zestawy, a otrzymasz każdą kombinację tych dwóch. Podziel powiązane dane na wiele wyborów, a teraz wykonałeś wiele zapytań dla wątpliwej korzyści i zacząłeś wykonywać za to zadanie MySQL.
cHao
8

Skonstruuj zarówno oddzielne zapytania, jak i połączenia, a następnie zmień czas na każde z nich - nic nie pomaga bardziej niż liczby w świecie rzeczywistym.

Jeszcze lepiej - dodaj „EXPLAIN” na początku każdego zapytania. Dzięki temu dowiesz się, ile podzapytań używa MySQL, aby odpowiedzieć na Twoje żądanie danych, oraz ile wierszy skanuje dla każdego zapytania.

DreadPirateShawn
źródło
7

W zależności od złożoności bazy danych w porównaniu ze złożonością programisty, może być prostsze wykonanie wielu wywołań SELECT.

Spróbuj uruchomić statystyki bazy danych zarówno dla JOIN, jak i dla wielu SELECTS. Sprawdź, czy w Twoim środowisku JOIN jest szybsze / wolniejsze niż SELECT.

Z drugiej strony, jeśli zmiana na JOIN oznaczałaby dodatkowy dzień / tydzień / miesiąc pracy deweloperskiej, trzymałbym się wielu SELECT

Twoje zdrowie,

BLT

glasnt
źródło
5

Z mojego doświadczenia wynika, że ​​zwykle szybsze jest uruchamianie kilku zapytań, szczególnie podczas pobierania dużych zestawów danych.

Podczas interakcji z bazą danych z innej aplikacji, takiej jak PHP, istnieje argument, że jedna podróż do serwera jest większa niż wiele.

Istnieją inne sposoby, aby ograniczyć liczbę podróży do serwera i nadal uruchamiać wiele zapytań, które często są nie tylko szybsze, ale także ułatwiają czytanie aplikacji - na przykład mysqli_multi_query.

Nie jestem nowicjuszem, jeśli chodzi o SQL, myślę, że istnieje tendencja wśród programistów, zwłaszcza juniorów, do spędzania dużo czasu na pisaniu bardzo sprytnych łączeń, ponieważ wyglądają inteligentnie, podczas gdy w rzeczywistości istnieją sprytne sposoby wydobywania danych, które wyglądają prosty.

Ostatni akapit był osobistą opinią, ale mam nadzieję, że to pomoże. Zgadzam się jednak z innymi, którzy mówią, że powinieneś testować. Żadne podejście nie jest srebrną kulą.

Chłopiec o imieniu Su
źródło
Tak, powinniśmy uwzględnić nie tylko same zapytania, ale także przetwarzanie danych wewnątrz aplikacji. W przypadku pobierania danych z zewnętrznymi złączeniami istnieje pewna nadmiarowość (czasami może być naprawdę ogromna), która musi być uporządkowana przez aplikację (zwykle w jakiejś bibliotece ORM), więc podsumowując, pojedyncze zapytanie SELECT z JOIN może zużywać więcej procesora i czas niż dwa proste WYBORY
JustAMartin
4

To, czy powinieneś używać złączenia, zależy przede wszystkim od tego, czy połączenie ma sens . Dopiero w tym momencie wydajność jest nawet czymś, co należy wziąć pod uwagę, ponieważ prawie we wszystkich innych przypadkach będzie to znacznie gorsze wydajność .

Różnice w wydajności będą w dużej mierze związane z tym, jak powiązane są informacje, o które prosisz. Łączy pracę i działa szybko, gdy dane są powiązane i poprawnie indeksujesz elementy, ale często skutkują pewną redundancją, a czasem większą liczbą wyników niż potrzeba. A jeśli twoje zbiory danych nie są bezpośrednio powiązane, umieszczenie ich w jednym zapytaniu da w wyniku tak zwany iloczyn kartezjański (w zasadzie wszystkie możliwe kombinacje wierszy), co prawie nigdy nie jest tym, czego chcesz.

Jest to często spowodowane relacjami „wiele do jednego do wielu”. Na przykład odpowiedź HoldOffHungera wspominała o jednym zapytaniu dotyczącym postów, tagów i komentarzy. Komentarze są powiązane z postem, tak jak tagi ... ale tagi nie są związane z komentarzami.

+------------+     +---------+     +---------+
|  comment   |     |   post  |     |  tag    |
|------------|*   1|---------|1   *|---------|
| post_id    |-----| post_id |-----| post_id |
| comment_id |     | ...     |     | tag_id  |
| user_id    |     |         |     | ...     |
| ...        |     |         |     | ...     |
+------------+     +---------+     +---------+

W takim przypadku zdecydowanie lepiej jest, aby były to co najmniej dwa oddzielne zapytania. Jeśli spróbujesz połączyć tagi i komentarze, ponieważ nie ma między nimi bezpośredniego związku, otrzymasz każdą możliwą kombinację tagu i komentarza. many * many == manymany. Poza tym, ponieważ posty i tagi nie są ze sobą powiązane, możesz wykonać te dwa zapytania równolegle, co prowadzi do potencjalnego zysku.

Rozważmy jednak inny scenariusz: chcesz, aby komentarze były dołączone do posta i dane kontaktowe komentujących.

 +----------+     +------------+     +---------+
 |   user   |     |  comment   |     |   post  |
 |----------|1   *|------------|*   1|---------|
 | user_id  |-----| post_id    |-----| post_id |
 | username |     | user_id    |     | ...     |
 | ...      |     | ...        |     +---------+
 +----------+     +------------+

W tym miejscu powinieneś rozważyć dołączenie. Oprócz tego, że jest znacznie bardziej naturalnym zapytaniem, większość systemów baz danych (w tym MySQL) ma wielu inteligentnych ludzi, którzy wkładają dużo pracy w optymalizację zapytań, tak jak to. W przypadku oddzielnych zapytań, ponieważ każde zapytanie zależy od wyników poprzedniego, zapytania nie mogą być wykonywane równolegle, a całkowity czas staje się nie tylko faktycznym czasem wykonywania zapytań, ale także czasem spędzonym na pobieraniu wyników, przesiewaniu za ich pośrednictwem w poszukiwaniu identyfikatorów dla następnego zapytania, łączenia wierszy itp.

cHao
źródło
Jeśli w drugim scenariuszu pobierasz wiele kolumn użytkowników (i ci sami użytkownicy komentują więcej niż raz), nadal pozostaje otwarte pytanie, czy najlepiej są one pobierać w oddzielnym zapytaniu.
Adrian Baker
@AdrianBaker: Tak jak powiedziałem, wielu sprytnych ludzi wkłada w to mnóstwo ciężkiej pracy. Gdybym miał zoptymalizować mój serwer SQL, moim pierwszym pomysłem byłoby użycie kompresji, która wyeliminowałaby ogromną ilość nadmiarowości bez zmiany kodu dużo. Optymalizacje na wyższym poziomie obejmowałyby reorganizację wyniku w tabele i wysłanie ich wraz z krotkami identyfikatorów wierszy, które biblioteka klienta mogłaby następnie łatwo złożyć na boku w razie potrzeby.
cHao
Obie te optymalizacje mogą zdziałać cuda w przypadku łączenia w celu zmniejszenia lub nawet wyeliminowania nadmiarowości, ale niewiele może pomóc w z natury szeregowych zapytaniach, które musiałbyś zrobić, aby pobrać powiązane rekordy.
cHao
3

Czy będzie szybszy pod względem przepustowości? Prawdopodobnie. Ale może również blokować więcej obiektów bazy danych naraz (w zależności od bazy danych i schematu), a tym samym zmniejsza współbieżność. Z mojego doświadczenia wynika, że ​​ludzie często są wprowadzani w błąd argumentem „mniej połączeń do bazy danych w obie strony”, podczas gdy w rzeczywistości w większości systemów OLTP, w których baza danych znajduje się w tej samej sieci LAN, prawdziwym wąskim gardłem rzadko jest sieć.

Ramon
źródło
2

Oto link ze 100 przydatnymi zapytaniami, które są testowane w bazie danych Oracle, ale pamiętaj, że SQL jest standardem, czym różnią się między Oracle, MS SQL Server, MySQL i innymi bazami danych to dialekt SQL:

http://javaforlearn.com/100-sql-queries-learn/

S. Mayol
źródło
1

Istnieje kilka czynników, co oznacza, że ​​nie ma odpowiedzi binarnej. Pytanie, co jest najlepsze dla wydajności, zależy od środowiska. Nawiasem mówiąc, jeśli twój pojedynczy wybór z identyfikatorem nie jest podsekundą, coś może być nie tak z twoją konfiguracją.

Prawdziwym pytaniem, które należy zadać, jest to, w jaki sposób chcesz uzyskać dostęp do danych. Pojedyncze wybory obsługują późne wiązanie. Na przykład, jeśli potrzebujesz tylko informacji o pracownikach, możesz wybrać je z tabeli Pracownicy. Relacje klucza obcego mogą być używane do pobierania powiązanych zasobów w późniejszym czasie i w razie potrzeby. Wybrane elementy będą już miały klucz do wskazania, więc powinny być niezwykle szybkie, a Ty musisz tylko odzyskać to, czego potrzebujesz. Zawsze należy brać pod uwagę opóźnienia w sieci.

Połączenia będą pobierać wszystkie dane naraz. Jeśli generujesz raport lub wypełniasz siatkę, może to być dokładnie to, czego chcesz. Skompilowane i zoptymalizowane łączenia będą po prostu szybsze niż pojedyncze selekcje w tym scenariuszu. Pamiętaj, że łączenia ad-hoc mogą nie być tak szybkie - powinieneś je skompilować (do przechowywanego procesu). Szybka odpowiedź zależy od planu wykonania, który szczegółowo określa, jakie kroki podejmuje DBMS w celu pobrania danych.

dr.lockett
źródło
0

Tak, jedno zapytanie wykorzystujące JOINS byłoby szybsze. Chociaż bez znajomości relacji między tabelami, do których wysyłasz zapytanie, rozmiaru zbioru danych lub lokalizacji kluczy podstawowych, prawie niemożliwe jest określenie, o ile szybciej.

Dlaczego nie przetestować obu scenariuszy, wtedy będziesz wiedział na pewno ...

Mathew
źródło