Ich habe daran gearbeitet, eine Abfrage zu schreiben, die unsere sehr große Datenbank trifft, um maximale Abrechnungsbeträge (A und B, in diesem Beispiel) für Kunden zurück zu ziehen. Wir möchten die maximale A/B für jeden Kunden für den letzten Monat und die maximale A/B für das vergangene Jahr zurückziehen.Oracle-Abfrage läuft sehr langsam aufgrund großer Datensatz und negative Werte
Ein Problem, das wir in unserer Abrechnungsdatenbank festgestellt haben, ist die Art und Weise, in der "stornierte" Rechnungen gespeichert werden. Dies geschieht durch Hinzufügen einer zweiten, negativen Version des ersten Rechnungsdatensatzes zur Abrechnungstabelle. Wie so:
In diesem Fall 41040 die falsche Rechnung war, so eine negative Version des Datensatzes wurde hinzugefügt. Wenn ich jedoch versuche, den Maximalwert für diese Spalte auszuwählen, erhalte ich immer 41040 anstelle des korrekten berechneten Werts von 50. Diese Tabelle scheint diese falschen Rechnungen in keiner Weise zu markieren, die es leicht machen würde Aussortieren.
Meine aktuelle Lösung war es, den Höchstwert der ID-Spalte als die richtige Rechnung zu nehmen. Dies macht die Annahme, dass die endgültige Rechnung, die für einen Monat eingegeben wurde, die richtige ist.
Dies scheint die richtigen Daten zurück zu bringen, aber die Abfrage läuft unglaublich langsam auf dem großen Datensatz, und ich habe keinen Schreibzugriff auf diese Tabelle zum Hinzufügen oder Anzeigen von Indizes. Es gibt 98.007.807 Zeilen insgesamt und 1.596.491 eindeutige Kunden. Gibt es trotzdem eine Optimierung der Abfrage zur Verbesserung der Performance?
select mth.KY_CUSTOMER_NO,max(QY_MTH_BILLED_A) as QY_MTH_BILLED_A, max(QY_MTH_B) as QY_MTH_BILLING_B, max.MAX_BILLING_A, max.MAX_BILLING_B
from (
--Get the max A/B values for the past month
select m.*
from CUSTOMER_USAGE m
where rev_year = to_number(to_char(sysdate,'yyyy'))
and rev_mth in (to_number(to_char(add_months(sysdate, -1), 'mm')),to_number(to_char(sysdate,'mm')))
and ID in (select max(ID) from CUSTOMER_USAGE where KY_CUSTOMER_NO = m.KY_CUSTOMER_NO group by rev_mth, rev_year)
) mth join
(
--Get the max A/B values for the past year
select KY_CUSTOMER_NO, max(QY_MTH_B) as MAX_BILLING_B, max(QY_MTH_BILLED_A) as MAX_BILLING_A from CUSTOMER_USAGE m
where DT_ADDED > current_timestamp - 365 ID in (select max(ID) from CUSTOMER_USAGE where KY_CUSTOMER_NO = m.KY_CUSTOMER_NO group by rev_mth, rev_year)
group by KY_CUSTOMER_NO
) max on mth.KY_CUSTOMER_NO = max.KY_CUSTOMER_NO
group by mth.KY_CUSTOMER_NO, max.MAX_BILLING_KVA, max.MAX_BILLING_KW
Welche Index (e) gibt es und was ist der aktuelle Abfrageplan? –