Ich habe die folgende Abfrage aufvermeiden Wiederholung Bedingung in Auswahlabfrage
postgresql ausgeführt werdenSELECT COUNT(DISTINCT id_client) FROM contract c
INNER JOIN bundle b ON c.bundle_id = b.id
INNER JOIN payment_method pm ON pm.id = c.payment_method_id
WHERE country_id=1 AND b.platform_id=1 AND pm.name <> 'RIB'
AND CONDITION_1
AND id_client NOT IN (
SELECT id_client FROM contract c1
INNER JOIN bundle b1 ON (c1.bundle_id = b1.id)
INNER JOIN payment_method pm1 ON pm1.id = c1.payment_method_id
WHERE c1.country_id=1 AND b1.platform_id=1 AND pm1.name <> 'RIB'
AND CONDITION_2);
Ich mag es nicht, weil es die gleiche Abfrage ist zweimal wiederholt, mit Ausnahme von CONDITION_1 und CONDITION_2 (und ich habe ein weiteres Beispiel wo es 3 mal wiederholt wird).
Es ist auch sehr langsam.
Ich habe versucht, es wie folgt zu umschreiben:
WITH
filter_cpm AS (
SELECT * FROM contract c
INNER JOIN bundle b ON b.id = c.bundle_id
INNER JOIN payment_method pm ON pm.id = c.payment_method_id
WHERE c.country_id = 1 AND b.platform_id = 1 AND pm.name <> 'RIB'
)
SELECT COUNT(DISTINCT id_client) FROM filter_cpm
WHERE CONDITION_1
AND id_client NOT IN (
SELECT id_client FROM filter_cpm
WHERE CONDITION_2);
Jetzt ist es trocken, aber es ist zwei mal langsamer.
Wie kann ich die Abfrage neu schreiben, um die gleiche (oder bessere) Leistung zu haben?
EDIT: Ich kann nicht zwei Bedingungen mit UND verbinden. Wenn beispielsweise CONDITION_1 und CONDITION_2 VIP sind, möchte ich Kunden auswählen, die von NOT VIP zu VIP re-qualifiziert wurden.
Danke für die Antwort. Ja, Ihre Abfrage liefert das gleiche Ergebnis wie zwei meiner Abfragen. Und es dauert 3 Minuten, genauso wie meine zweite Abfrage. Die erste wird in 1min30 –
ausgeführt. Sie könnten FILTER_CPM einschränken, um nur die Felder zurückzuziehen, die Sie tatsächlich benötigen. Von dem, was ich sehen kann, ist das einzige Feld, das tatsächlich verwendet wird, ID_CLIENT, aber ich habe natürlich keine Ahnung, was CONDITION_1 und CONDITION_2 sein könnten. Erstellen Sie dann vollständige Indizes für CONTRACT, BUNDLE und PAYMENT_METHOD für alle beteiligten Felder und prüfen Sie, ob Sie FULL TABLE SCANs in INDEX SCANs umwandeln können. –