2012-04-10 4 views
1

Ich habe die folgende Abfrage, die mir die richtigen Ergebnisse gibt. Aber es ist super langsam. Was es langsam macht, ist dieMySQL "Distinct" beitreten super langsam

AND a.id IN (SELECT id FROM st_address GROUP BY element_id) 

Teil. Die Abfrage sollte zeigen, aus welchen Ländern wir wie viele Bestellungen erhalten.
Eine Person kann mehrere Adressen haben, aber in diesem Fall wollen wir nur eine.
Ursache andernfalls wird die Bestellung mehrmals gezählt. Vielleicht gibt es einen besseren Weg, dies zu erreichen? Ein eindeutiger Beitritt zur Person oder etwas?

SELECT cou.title_en, COUNT(co.id), SUM(co.price) AS amount 
FROM customer_order co 
JOIN st_person p ON (co.person_id = p.id) 
JOIN st_address a ON (co.person_id = a.element_id AND a.element_type_id = 1) 
JOIN st_country cou ON (a.country_id = cou.id) 
WHERE order_status_id != 7 AND a.id IN (SELECT id FROM st_address GROUP BY element_id) 
GROUP BY cou.id 
+0

Ist die customer_order Tabelle, die die Liefer- oder Rechnungsadresse nicht verfolgen? Sicherlich ist es möglich, nur eine einzige Adresse für jede Bestellung zu bekommen? –

+0

Entfernen Sie die Gruppe, indem Sie von der Unterabfrage aus dies beheben –

+0

@Rory Der Kunde_Antrag verfolgt die Rechnungsadresse. Aber das ist oft nicht in dem Land, aus dem die Bestellung stammt. Die meisten unserer Kunden sind in Europa und die Bestellung pro Land. Aber das Rechnungszentrum ist oft irgendwo zentralisiert. – Remy

Antwort

0

Ich fand eine schnellere Lösung. Der Trick ist, eine Verknüpfung mit einer Sub-Abfrage:

JOIN (SELECT element_id, country_id, id FROM st_address WHERE element_type_id = 1 GROUP BY 

Dies ist die komplette Abfrage:

SELECT cou.title_en, COUNT(o.id), SUM(o.price) AS amount 
FROM customer_order o 
JOIN (SELECT element_id, country_id, id FROM st_address WHERE element_type_id = 1 GROUP BY element_id) AS a ON (o.person_id = a.element_id) 
JOIN st_country cou ON (a.country_id = cou.id) 
WHERE o.order_status_id != 7 
GROUP BY cou.id 
1

Haben Sie versucht, das IN durch ein EXISTS zu ersetzen?

Der EXISTS-Teil sollte die Unterabfrage stoppen, sobald die erste Zeile gefunden wurde, die die Bedingung erfüllt. Ich habe widersprüchliche Kommentare darüber gelesen, ob das tatsächlich passiert, also könntest du ein Limit 1 hineinwerfen, um zu sehen, ob du einen Gewinn erzielst.

+0

Das ist zwar viel schneller, zählt aber immer noch jede Adresse. – Remy

+0

Nein, das passiert nicht, wenn Sie die Verbindung zu der Adresstabelle entfernen und nur diese Unterabfrage beibehalten. –