2009-05-15 21 views
1

Ich habe zwei MySQL-Abfragen, die beide Daten in eine Tabelle einfügen. Beide haben das folgende Format:Vereinen Sie zwei MySQL-Abfragen mit einer UNION oder programmatisch

CREATE TABLE IF NOT EXISTS `data` (
`id` BIGINT NOT NULL AUTO_INCREMENT UNIQUE, 
PRIMARY KEY (`id`) 
) 
SELECT `field1`, `field2` 
WHERE `active` = 1 

Die einzigen Unterschiede zwischen den beiden Abfragen sind wie field1 und field2 bestimmt sind, und einige kleinere Unterschiede in den Bedingungen Klausel. Beide laufen bis zu 12.000 und mehr Datensätze.

Nun, was effizienter sein wird: separat

A. Führen Sie beide Abfragen:

if (mysql_query($query1)) { 
    return mysql_query($query2); 
} 
return false; 

B. OR verbinden die zwei Abfragen mit einer UNION und führen einmal:

$query = 'SELECT `field1`, `field2` WHERE `active` = 1 
      UNION 
      SELECT DO_ONE(`field1`), DO_TWO(`field2`) WHERE `active` = 1 
      ORDER BY `field1`'; 
return mysql_query('CREATE TABLE IF NOT EXISTS `data` (
`id` BIGINT NOT NULL AUTO_INCREMENT UNIQUE, 
PRIMARY KEY (`id`) 
) ' . $query) 

Die Daten von der einen Abfrage sind nutzlos ohne die Daten von der anderen, also müssen beide erfolgreich sein. DO_ONE und DO_TWO sind benutzerdefinierte MySQL-Funktionen, die die Felddaten gemäß einiger Spezifikationen ändern.

+0

zumindest oberflächlich, es sieht aus, als ob Sie aus früheren Läufen der Abfragen, wenn Ihre Zieltabelle existiert bereits erhalten links über Abschaum werden. Da Sie über einen automatisch generierten Primärschlüssel verfügen, können Sie auch so lange neue Datensätze in die Tabelle einfügen, wie Sie möchten (Ihnen bleibt wahrscheinlich der Speicherplatz vor dem Auslaufen der Zahlen erspart). –

+1

Die UNION-Version gewährleistet keine doppelten Datensätze in der Ergebnismenge. die separate Abfrage Version nicht. Nun, die "id" -Spalte stellt tatsächlich sicher, dass die Datensätze alle unterschiedlich sind, aber es könnten wiederholte Datensätze mit denselben Daten in den anderen Spalten (aber unterschiedlichen ID-Werten) vorkommen. Das ist wahrscheinlich wichtig - benutze UNION. –

Antwort

1

Aaronmccalls Antwort ist wahrscheinlich die beste überhaupt - der UNION-Ansatz macht alles in einem einzigen SQL-Aufruf. Im Allgemeinen wird das am "effizientesten" sein, aber es könnte Nebenprobleme geben, die ins Spiel kommen können und das Maß von "effizient" für Ihre spezielle Anwendung beeinflussen. Wenn die UNION eine temporäre Tabelle benötigt, um die Zwischenergebnisse zu sammeln, und Sie mit sehr großen Datenmengen arbeiten, könnte es in Ihrem Fall effizienter sein, zwei separate SELECTs in die neue Tabelle zu schreiben. Dies hängt von den internen Abläufen, Optimierungen usw. in der Datenbank-Engine ab (die sich je nach Version der verwendeten Datenbank-Engine ändern können).

Letztendlich ist die einzige Möglichkeit, Ihre Frage zu einer solchen speziellen Frage zu beantworten, die Zeitplanung für Ihre spezielle Anwendung und Umgebung.

Sie sollten auch bedenken, dass der Unterschied zwischen der Zeit für zwei separate Abfragen vs eine "All in One" Abfrage im Großen Schema der Dinge unbedeutend sein könnte ... Sie sprechen wahrscheinlich über einen Unterschied von a einige Millisekunden (oder sogar Mikrosekunden?), es sei denn, Ihre MySQL-Datenbank befindet sich auf einem separaten Server mit großen Latenzproblemen. Wenn Sie Tausende von diesen Anrufen in einem Schuss tun, dann kann der Unterschied erheblich sein, aber wenn Sie nur einen oder zwei dieser Anrufe machen und Ihre Anwendung 99.99% ihrer Zeit damit verbringt, andere Dinge auszuführen, dann ist der Unterschied zwischen den zwei werden wahrscheinlich nicht einmal bemerkt werden.

--- Lawrence

+0

Eine der Abfragen wird in Millisekunden ausgeführt. Die andere dauert Minuten wegen einer ziemlich komplizierten Storek-Prozedur. Ich habe mich entschieden, vom gespeicherten Proc wegzugehen, um die Abfrage zu optimieren. – Jrgns

0

Ihre Optionen machen verschiedene Dinge. Der erste gibt die Ergebnisse der zweiten Abfrage zurück, wenn die erste Abfrage korrekt ausgeführt wird (was BTW unabhängig von den Ergebnissen ist, die es zurückgibt, es kann einen leeren Rowset zurückgeben). Der zweite gibt die Ergebnisse der ersten Abfrage und der zweiten Abfrage zusammen zurück. Die erste Option scheint mir ziemlich nutzlos, was Sie wahrscheinlich erreichen wollen ist, was Sie mit der UNION gemacht haben (es sei denn, ich habe Sie missverstanden).

EDIT: Nachdem Sie Ihren Kommentar zu lesen, ich glaube, Sie nach so etwas wie dieses sind:

SELECT wahr, wo (EXISTS (SELECT Feld1, Feld2 ...) und exists (SELECT Field1, Feld2 ...)) .

Auf diese Weise haben Sie nur eine Abfrage an die DB, die besser skaliert, weniger Ressourcen aus dem Verbindungspool und verdoppeln nicht die Auswirkungen der Latenz, wenn Sie Ihre DB-Engine auf einem anderen Server haben, aber Sie werden Unterbrechen Sie die Abfrage weiterhin, wenn die erste Bedingung fehlschlägt. Dies ist die Leistungsverbesserung, nach der Sie bei den geschachtelten getrennten Abfragen gesucht haben.

Als eine Optimierung, versuchen Sie zuerst die Bedingung, die schneller ausgeführt wird, falls sie nicht gleich sind. Ich nehme an, dass, wenn einer von ihnen erfordert, diese Feldberechnungen langsamer wären.

+0

Keine der Optionen gibt Resultsets zurück. Beide geben false zurück, wenn eine oder beide Abfragen fehlgeschlagen sind, oder ein Ergebnisobjekt. Da diese Abfragen nur Daten einfügen, müssen die Ergebnisobjekte nicht abgefragt werden. Es wird nur als Boolescher Wert interpretiert, um zu sehen, ob die Einfügung erfolgreich ausgeführt wurde. – Jrgns

+0

Ich denke, Sie meinen, dass im Falle der Union, wenn die erste leere zurückgibt, wird die zweite leer wegen der Fragen, die Sie tun. Was UNION tun wird, ist die Ergebnisse der einzelnen Abfragen zusammenzufassen, was bedeutet, dass Sie einen WAHR erhalten würden, wenn der eine Datensatz zurückgibt und der andere nicht. Wie auch immer, ich werde meine Antwort jetzt bearbeiten, dass ich weiß, was Sie ein bisschen besser wollen. – palako

0

Der UNION-Ansatz sollte auf jeden Fall schneller sein, da zwei mysql-API-Aufrufe von php gegen eins gemacht werden müssen.

Verwandte Themen