Sind JOIN-Abfragen schneller als mehrere Abfragen? (Sie führen Ihre Hauptabfrage aus und dann viele andere SELECTs basierend auf den Ergebnissen Ihrer Hauptabfrage.)
Ich frage, weil das Beitreten VIEL das Design meiner Anwendung erschweren würde
Wenn sie schneller sind, kann sich jemand ungefähr wie viel annähern? Wenn es 1,5x ist, ist es mir egal, aber wenn es 10x ist, denke ich, dass ich es tue.
mysql
database
join
query-optimization
Thomas Bonini
quelle
quelle
Antworten:
Dies ist viel zu vage, um Ihnen eine Antwort zu geben, die für Ihren speziellen Fall relevant ist. Es hängt von vielen Dingen ab. Jeff Atwood (Gründer dieser Seite) hat tatsächlich darüber geschrieben . Wenn Sie jedoch die richtigen Indizes haben und Ihre JOINs ordnungsgemäß ausführen, ist es in der Regel schneller, eine Fahrt durchzuführen als mehrere.
quelle
Für innere Verknüpfungen ist eine einzelne Abfrage sinnvoll, da Sie nur übereinstimmende Zeilen erhalten. Bei Linksverknüpfungen sind mehrere Abfragen viel besser. Sehen Sie sich den folgenden Benchmark an, den ich durchgeführt habe:
Einzelabfrage mit 5 Joins
Abfrage: 8.074508 Sekunden
Ergebnisgröße: 2268000
5 Abfragen hintereinander
kombinierte Abfragezeit : 0,00262 Sekunden
Ergebnisgröße: 165 (6 + 50 + 7 + 12 + 90)
.
Beachten Sie, dass wir in beiden Fällen die gleichen Ergebnisse erhalten (6 x 50 x 7 x 12 x 90 = 2268000).
Linke Verknüpfungen verbrauchen exponentiell mehr Speicher mit redundanten Daten.
Das Speicherlimit ist möglicherweise nicht so schlecht, wenn Sie nur zwei Tabellen verbinden, im Allgemeinen jedoch drei oder mehr, und es werden unterschiedliche Abfragen wert.
Nebenbei bemerkt, mein MySQL-Server befindet sich direkt neben meinem Anwendungsserver. Die Verbindungszeit ist also vernachlässigbar. Wenn Ihre Verbindungszeit in Sekunden liegt, gibt es möglicherweise einen Vorteil
Frank
quelle
Diese Frage ist alt, aber es fehlen einige Benchmarks. Ich habe JOIN mit seinen 2 Konkurrenten verglichen:
WHERE IN(...)
oder einem gleichwertigenDas Ergebnis ist klar: Unter MySQL geht
JOIN
es viel schneller. N + 1-Abfragen können die Leistung einer Anwendung drastisch beeinträchtigen:Das heißt, es sei denn, Sie wählen viele Datensätze aus, die auf eine sehr kleine Anzahl unterschiedlicher ausländischer Datensätze verweisen. Hier ist ein Benchmark für den Extremfall:
Dies ist in einer typischen Anwendung sehr unwahrscheinlich, es sei denn, Sie treten einer-zu-viele-Beziehung bei. In diesem Fall befindet sich der Fremdschlüssel in der anderen Tabelle und Sie duplizieren die Haupttabellendaten häufig.
Wegbringen:
JOIN
Weitere Informationen finden Sie in meinem Artikel über Medium .
quelle
Ich bin tatsächlich zu dieser Frage gekommen, um selbst nach einer Antwort zu suchen, und nachdem ich die gegebenen Antworten gelesen habe, kann ich nur zustimmen, dass der beste Weg, die Leistung von DB-Abfragen zu vergleichen, darin besteht, reale Zahlen zu erhalten, da nur zu viele Variablen berücksichtigt werden müssen ABER ich denke auch, dass ein Vergleich der Zahlen zwischen ihnen in fast allen Fällen nicht gut ist. Was ich meine ist, dass die Zahlen immer mit einer akzeptablen Zahl verglichen werden sollten und definitiv nicht miteinander verglichen werden sollten.
Ich kann verstehen, dass eine Abfrage etwa 0,02 Sekunden und die andere 20 Sekunden dauert, das ist ein enormer Unterschied. Was aber, wenn eine Abfragemethode 0,0000000002 Sekunden und die andere 0,0000002 Sekunden dauert? In beiden Fällen ist eine Möglichkeit satte 1000-mal schneller als die andere, aber ist sie im zweiten Fall wirklich immer noch "satte"?
Fazit, wie ich es persönlich sehe: Wenn es gut funktioniert, entscheiden Sie sich für die einfache Lösung.
quelle
Habe einen Schnelltest durchgeführt, bei dem eine Zeile aus einer Tabelle mit 50.000 Zeilen ausgewählt und mit einer Zeile aus einer Tabelle mit 100.000 Zeilen verbunden wurde. Im Grunde sah es so aus:
vs.
Die Zwei-Auswahl-Methode dauerte 3,7 Sekunden für 50.000 Lesevorgänge, während die JOIN-Methode auf meinem langsamen Computer zu Hause 2,0 Sekunden dauerte. INNER JOIN und LEFT JOIN machten keinen Unterschied. Das Abrufen mehrerer Zeilen (z. B. mit IN SET) ergab ähnliche Ergebnisse.
quelle
Die eigentliche Frage ist: Haben diese Datensätze eine Eins-zu-Eins-Beziehung oder eine Eins-zu-Viele-Beziehung ?
TLDR Antwort:
Wenn eins zu eins, verwenden Sie eine
JOIN
Anweisung.Verwenden Sie bei Eins-zu-Viele eine (oder mehrere)
SELECT
Anweisungen mit serverseitiger Codeoptimierung.Warum und wie SELECT zur Optimierung verwendet wird
SELECT
Das Erstellen (mit mehreren Abfragen anstelle von Verknüpfungen) für eine große Gruppe von Datensätzen, die auf einer Eins-zu-Viele-Beziehung basieren, führt zu einer optimalen Effizienz, daJOIN
das Problem mit einem exponentiellen Speicherverlust verbunden ist. Holen Sie sich alle Daten und sortieren Sie sie mit einer serverseitigen Skriptsprache aus:Ergebnisse:
Hier erhalte ich alle Datensätze in einer Select-Anweisung. Dies ist besser als
JOIN
, wenn eine kleine Gruppe dieser Datensätze einzeln als Unterkomponente einer anderen Abfrage abgerufen wird. Dann analysiere ich es mit serverseitigem Code, der ungefähr so aussieht ...Wann sollte JOIN nicht zur Optimierung verwendet werden?
JOIN
Wenn eine große Gruppe von Datensätzen auf der Grundlage einer Eins-zu-Eins-Beziehung zu einem einzelnen Datensatz erstellt wird, ergibt sich eine optimale Effizienz im Vergleich zu mehreren aufeinanderfolgendenSELECT
Anweisungen, die einfach den nächsten Datensatztyp erhalten.Ist
JOIN
aber ineffizient, wenn Datensätze mit einer Eins-zu-Viele-Beziehung abgerufen werden.Beispiel: Die Datenbank Blogs enthält 3 interessante Tabellen: Blogpost, Tag und Kommentar.
Wenn es 1 Blogpost, 2 Tags und 2 Kommentare gibt, erhalten Sie folgende Ergebnisse:
Beachten Sie, wie jeder Datensatz dupliziert wird. Okay, 2 Kommentare und 2 Tags sind 4 Zeilen. Was ist, wenn wir 4 Kommentare und 4 Tags haben? Sie erhalten nicht 8 Zeilen - Sie erhalten 16 Zeilen:
Wenn Sie mehr Tabellen, mehr Datensätze usw. hinzufügen, steigt das Problem schnell auf Hunderte von Zeilen an, die alle mit größtenteils redundanten Daten gefüllt sind.
Was kosten Sie diese Duplikate? Speicher (im SQL Server und der Code, der versucht, die Duplikate zu entfernen) und Netzwerkressourcen (zwischen SQL Server und Ihrem Codeserver).
Quelle: https://dev.mysql.com/doc/refman/8.0/en/nested-join-optimization.html ; https://dev.mysql.com/doc/workbench/en/wb-relationship-tools.html
quelle
Konstruieren Sie sowohl separate Abfragen als auch Verknüpfungen und setzen Sie dann jede Zeit ab - nichts hilft mehr als reale Zahlen.
Dann noch besser - fügen Sie "EXPLAIN" am Anfang jeder Abfrage hinzu. Hier erfahren Sie, wie viele Unterabfragen MySQL verwendet, um Ihre Datenanforderung zu beantworten, und wie viele Zeilen für jede Abfrage gescannt wurden.
quelle
Abhängig von der Komplexität der Datenbank im Vergleich zur Komplexität der Entwickler kann es einfacher sein, viele SELECT-Aufrufe auszuführen.
Versuchen Sie, einige Datenbankstatistiken sowohl für JOIN als auch für mehrere SELECTS auszuführen. Überprüfen Sie, ob in Ihrer Umgebung der JOIN schneller / langsamer als der SELECT ist.
Andererseits würde ich mich an mehrere SELECTs halten, wenn das Ändern in ein JOIN einen zusätzlichen Tag / eine Woche / einen Monat Entwicklungsarbeit bedeuten würde
Prost,
BLT
quelle
Nach meiner Erfahrung ist es normalerweise schneller, mehrere Abfragen auszuführen, insbesondere beim Abrufen großer Datenmengen.
Bei der Interaktion mit der Datenbank von einer anderen Anwendung wie PHP gibt es das Argument einer Reise zum Server über mehrere.
Es gibt andere Möglichkeiten, die Anzahl der Fahrten zum Server zu begrenzen und dennoch mehrere Abfragen auszuführen, die häufig nicht nur schneller sind, sondern auch das Lesen der Anwendung erleichtern - beispielsweise mysqli_multi_query.
Ich bin kein Anfänger, wenn es um SQL geht. Ich denke, es gibt eine Tendenz für Entwickler, insbesondere für Junioren, viel Zeit damit zu verbringen, sehr clevere Joins zu schreiben, weil sie intelligent aussehen, während es tatsächlich intelligente Möglichkeiten gibt, Daten zu extrahieren, die aussehen einfach.
Der letzte Absatz war eine persönliche Meinung, aber ich hoffe, das hilft. Ich stimme jedoch den anderen zu, die sagen, Sie sollten Benchmarks erstellen. Keiner der Ansätze ist eine Silberkugel.
quelle
Ob Sie einen Join verwenden sollten, hängt in erster Linie davon ab, ob ein Join sinnvoll ist . Erst zu diesem Zeitpunkt ist die Leistung überhaupt zu berücksichtigen, da fast alle anderen Fälle zu einer deutlich schlechteren Leistung führen.
Leistungsunterschiede hängen weitgehend davon ab, in welchem Zusammenhang die von Ihnen abgefragten Informationen stehen. Joins funktionieren und sind schnell, wenn die Daten in Beziehung stehen und Sie die Daten korrekt indizieren. Sie führen jedoch häufig zu Redundanz und manchmal zu mehr Ergebnissen als erforderlich. Und wenn Ihre Datensätze nicht direkt miteinander verbunden sind, führt das Einfügen in eine einzelne Abfrage zu einem sogenannten kartesischen Produkt (im Grunde alle möglichen Kombinationen von Zeilen), was fast nie das ist, was Sie wollen.
Dies wird häufig durch viele-zu-eins-zu-viele-Beziehungen verursacht. In der Antwort von HoldOffHunger wurde beispielsweise eine einzelne Abfrage nach Posts, Tags und Kommentaren erwähnt. Kommentare beziehen sich auf einen Beitrag, ebenso wie Tags ... aber Tags haben nichts mit Kommentaren zu tun.
In diesem Fall ist es eindeutig besser, wenn dies mindestens zwei separate Abfragen sind. Wenn Sie versuchen, Tags und Kommentare zu verknüpfen, da keine direkte Beziehung zwischen beiden besteht, erhalten Sie jede mögliche Kombination aus Tag und Kommentar.
many * many == manymany
. Abgesehen davon können Sie diese beiden Abfragen parallel ausführen, da Beiträge und Tags nicht miteinander zusammenhängen, was zu einem potenziellen Gewinn führt.Betrachten wir jedoch ein anderes Szenario: Sie möchten, dass die Kommentare an einen Beitrag angehängt werden und die Kontaktinformationen der Kommentatoren.
Hier sollten Sie einen Join in Betracht ziehen. Abgesehen davon, dass es sich um eine viel natürlichere Abfrage handelt, haben die meisten Datenbanksysteme (einschließlich MySQL) viele kluge Leute, die viel harte Arbeit in die Optimierung von Abfragen investieren. Bei separaten Abfragen können die Abfragen nicht parallel ausgeführt werden, da jede Abfrage von den Ergebnissen der vorherigen Abfrage abhängt. Die Gesamtzeit wird nicht nur zur tatsächlichen Ausführungszeit der Abfragen, sondern auch zur Zeit, die zum Abrufen der Ergebnisse und zum Sieben aufgewendet wird durch sie nach IDs für die nächste Abfrage, Verknüpfung von Zeilen usw.
quelle
Wird es in Bezug auf den Durchsatz schneller sein? Wahrscheinlich. Es werden jedoch möglicherweise auch mehr Datenbankobjekte gleichzeitig gesperrt (abhängig von Ihrer Datenbank und Ihrem Schema) und dadurch die Parallelität verringert. Nach meiner Erfahrung werden Menschen häufig durch das Argument "weniger Datenbank-Roundtrips" irregeführt, wenn in der Realität auf den meisten OLTP-Systemen, auf denen sich die Datenbank im selben LAN befindet, der eigentliche Engpass selten das Netzwerk ist.
quelle
Hier ist ein Link mit 100 nützlichen Abfragen, die in der Oracle-Datenbank getestet werden. Beachten Sie jedoch, dass SQL ein Standard ist. Was sich zwischen Oracle, MS SQL Server, MySQL und anderen Datenbanken unterscheidet, ist der SQL-Dialekt:
http://javaforlearn.com/100-sql-queries-learn/
quelle
Es gibt mehrere Faktoren, was bedeutet, dass es keine binäre Antwort gibt. Die Frage, was für die Leistung am besten ist, hängt von Ihrer Umgebung ab. Übrigens, wenn Ihre Einzelauswahl mit einer Kennung nicht unter einer Sekunde liegt, stimmt möglicherweise etwas mit Ihrer Konfiguration nicht.
Die eigentliche Frage ist, wie Sie auf die Daten zugreifen möchten. Einzelauswahl unterstützt die späte Bindung. Wenn Sie beispielsweise nur Mitarbeiterinformationen wünschen, können Sie diese aus der Tabelle Mitarbeiter auswählen. Die Fremdschlüsselbeziehungen können verwendet werden, um verwandte Ressourcen zu einem späteren Zeitpunkt und nach Bedarf abzurufen. Die Auswahlen haben bereits einen Schlüssel, auf den sie verweisen können, sodass sie extrem schnell sein sollten und Sie nur das abrufen müssen, was Sie benötigen. Die Netzwerklatenz muss immer berücksichtigt werden.
Joins rufen alle Daten auf einmal ab. Wenn Sie einen Bericht erstellen oder ein Raster füllen, ist dies möglicherweise genau das, was Sie möchten. Kompilierte und optomisierte Verknüpfungen sind in diesem Szenario einfach schneller als einzelne Auswahlen. Denken Sie daran, dass Ad-hoc-Verknüpfungen möglicherweise nicht so schnell sind - Sie sollten sie kompilieren (in einen gespeicherten Prozess). Die Geschwindigkeitsantwort hängt vom Ausführungsplan ab, in dem genau angegeben ist, welche Schritte das DBMS zum Abrufen der Daten unternimmt.
quelle
Ja, eine Abfrage mit JOINS wäre schneller. Ohne die Beziehungen der von Ihnen abgefragten Tabellen, die Größe Ihres Datasets oder die Position der Primärschlüssel zu kennen, ist es fast unmöglich zu sagen, wie viel schneller.
Testen Sie beide Szenarien, dann wissen Sie sicher ...
quelle