2016-04-18 8 views
2
verwirrend

Ich habe eine MySQL-AbfrageZeilen Spalte in Query Plan

SELECT TE.company_id, 
     SUM(TE.debit- TE.credit) As summation 
FROM Transactions T JOIN Transaction_E TE2 
     ON (T.parent_id = TE2.transaction_id) 
JOIN Transaction_E TE 
     ON (TE.transaction_id = T.id AND TE.company_id IS NOT NULL) 
JOIN Accounts A 
     ON (TE2.account_id=A.id AND A.deactivated_timestamp=0) 
WHERE (TE.company_id IN (1,2)) 
    AND A.user_id=2341 GROUP BY TE.company_id; 

Wenn ich die Abfrage erklären, ist der Plan für sie wie (Gesamt):

| Select type | table | type | rows | 
------------------------------------- 
| SIMPLE  | A  | ref | 2 | 
| SIMPLE  | TE2 | ref | 17 | 
| SIMPLE  | T  | ref | 1 | 
| SIMPLE  | TE | ref | 1 | 

Aber wenn ich ein count (*) für die gleiche Abfrage (anstelle von SUM (..)), dann zeigt es, dass es ~ 40k Zeilen für eine bestimmte company_id gibt. Was ich nicht verstehe ist, warum der Abfrageplan zeigt, dass nur wenige Zeilen gescannt werden, während mindestens 40.000 Zeilen verarbeitet werden. Was bedeutet die Zeilenspalte im Abfrageplan? Stellt es nicht die Anzahl der Zeilen dar, die in dieser Tabelle verarbeitet werden? In diesem Fall sollte es höchstens 2 * 17 * 1 * 1 = 34 Reihen sein?

Antwort

0

Der Abfrageplan zeigt nur eine hohe Beurteilung der erwarteten Anzahl von Zeilen pro Tabelle, um das Endergebnis zu erfüllen. Es soll als ein Werkzeug verwendet werden, um zu beurteilen, wie der Optimierer Ihre Abfrage "sieht", und um ein wenig zu helfen, falls die Abfrageleistung schlechter ist oder verbessert werden kann.

Es besteht immer die Möglichkeit, dass der Abfrageplan auf einem früheren Snapshot von Statistiken basiert und daher nicht als bare Münze angenommen werden sollte, insbesondere wenn es um Kardinalität geht.

+0

Danke für die Antwort, aber es ist immer noch ein großer Unterschied zwischen dem, was es vorschlägt (~ 34 Zeilen) und was es endet (40k Zeilen). Wie kommt es mit diesen Zahlen? diese Zahlen sehen mich jetzt zufällig – Denorm

0

Nun, lassen Sie uns zunächst die rechnerische Fehler loszuwerden:

SELECT TE.company_id, TE.summation 
    FROM 
     (SELECT company_id, 
       SUM(debit - credit) As summation 
      FROM Transaction_E 
      WHERE company_id IN (1,2) 
    ) TE 
    JOIN Transactions T ON TE.transaction_id = T.id 
    JOIN Transaction_E TE2 ON T.parent_id = TE2.transaction_id 
    JOIN Accounts A  ON TE2.account_id = A.id 
     AND A.deactivated_timestamp = 0 
    WHERE A.user_id = 2341; 

Ihre Anfrage wahrscheinlich Addition der gleichen Firma mehrmals, bevor die GROUP BY tun. Meine Variante vermeidet diese Inflation des Aggregats.

Ich habe TE.company_id IS NOT NULL losgeworden, weil es redundant war.

Sehen Sie, was die EXPLAIN darüber sagt, dann lassen Sie uns Ihre Frage über EXPLAIN weiter diskutieren.

+0

Ich versuchte die Abfrage, die Sie vorgeschlagen. Es gibt zwei Probleme: erstens, das Ergebnis ist nicht das gleiche und zweitens, der Abfrageplan hat eine weitere Reihe von abgeleiteten Select-Typ und scannt ~ 40k Zeile für diese abgeleitete wählen – Denorm

+0

Ich fühlte, dass die Unterabfrage erforderlich war, um die richtigen Werte zu erhalten die Summe. Macht es? –

Verwandte Themen