2 Stimmen

MySQL Mehrere Unterabfragen im Vergleich zu ganzen Abfragen

Ich frage mich, welche Methode zum Abrufen von Daten aus einer MySQL-Datenbank bessere Leistungsmerkmale aufweist.

Verwendung von Unterabfragen innerhalb einer Hauptabfrage:

SELECT
(SELECT SUM(`number`) FROM `table`) as `number_sum`,
(SELECT MAX(`number`) FROM `table`) as `number_max`,
(SELECT MIN(`number`) FROM `table`) as `number_min`

Oder, 3 verschiedene SELECT Anweisungen, die dieselben Daten abrufen.

Vielen Dank im Voraus!

8voto

Michael Berkowski Punkte 260923

Da diese drei Aggregate aus der gleichen Tabelle mit dem gleichen WHERE Bedingungen haben, brauchen Sie keine Unterauswahlen. Alle drei Aggregate arbeiten mit der gleichen Zeilengruppierung (keine GROUP BY angegeben, also eine Zeile für die gesamte Tabelle), so dass sie alle in der SELECT Liste direkt.

SELECT
  SUM(number) AS number_sum,
  MAX(number) AS number_max,
  MIN(number) AS number_min
FROM `table`

Wenn eines der Aggregate auf verschiedenen Bedingungen basieren muss, würden Sie in einer WHERE Klausel, dann müssen Sie entweder eine Unterauswahl für die abweichende Bedingung verwenden oder eine kartesische Verknüpfung durchführen. Diese Unterauswahl und die folgende LEFT JOIN Methode sollte für Aggregate, die nur eine Zeile zurückgeben, leistungsmäßig gleichwertig sein:

SELECT
  /* Unique filtering condition - must be done in a subselect */
  (SELECT SUM(number) FROM `table` WHERE `somecolumn` = `somevalue`) AS number_sum,
  MAX(number) AS number_max,
  MIN(number) AS number_min
FROM `table`

Entsprechend der obigen Abfrage können Sie auch LEFT JOIN gegen eine Unterabfrage ohne ON Klausel . Dies sollte nur in Situationen geschehen, in denen Sie wissen, dass die Unterabfrage nur eine Zeile zurückgeben wird. Andernfalls erhalten Sie ein kartesisches Produkt - so viele Zeilen, wie eine Seite der Verknüpfung zurückgibt multipliziert mit die Anzahl der von der anderen Seite zurückgegebenen Zeilen.

Dies ist praktisch, wenn Sie mehrere Spalten mit einem Satz von WHERE Klauselbedingungen und ein paar Spalten mit einem anderen Satz von WHERE Bedingungen, sondern nur eine Reihe von jeder Seite des JOIN . In diesem Fall sollte es schneller gehen, wenn JOIN als zu tun zwei Unterauswahlen mit demselben WHERE Klausel.

Dies sollte schneller sein....

SELECT
  /* this one has two aggregates sharing a WHERE condition */
  subq.number_sum_filtered,
  subq.number_max_filtered,
  /* ...and two aggregates on the main table with no WHERE clause filtering */
  MAX(`table`.number) AS number_max,
  MIN(`table`.number) AS number_min
FROM
  `table`
  LEFT JOIN (
    SELECT 
       SUM(number) AS number_sum_filtered,
       MAX(number) AS number_max_filtered
    FROM `table`
    WHERE `somecolumn = `somevalue`
  ) subq /* No ON clause here since there's no common column to join on... */

Und dann das...

SELECT
  /* Two different subselects each over the same filtered set */
  (SELECT SUM(number) FROM `table` WHERE `somecolumn` = `somevalue`) AS number_sum_filtered,
  (SELECT MAX(number) FROM `table` WHERE `somecolumn` = `somevalue`) AS number_max_filtered,
  MAX(`table`.number) AS number_max,
  MIN(`table`.number) AS number_min
FROM
  `table`

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X