Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Vergleichen von zwei Cursorn in Oracle, anstatt MINUS zu verwenden

Ein MINUS ist eine Mengenoperation, die nicht nur die Ergebnisse der zweiten Abfrage von der ersten entfernt, sondern auch Duplikate entfernt, wenn sie in der ersten Menge erscheinen. Daher muss die angezeigte Abfrage immer die vollständige Ergebnismenge bilden aus TABLE_1, bevor es an den Benutzer zurückgegeben wird.

Wenn Sie sicher sein können, dass es keine Duplikate für den Trimemd-Kopf/das Wirksamkeitsdatum im ersten Satz gibt (oder Sie nicht möchten, dass solche Duplikate entfernt werden), können Sie es versuchen

SELECT  RTRIM(LTRIM(A.HEAD)), A.EFFECTIVE_DATE,
    FROM   TABLE_1 A
    WHERE  A.TYPE_OF_ACTION='6'
    AND    A.EFFECTIVE_DATE >= ADD_MONTHS(SYSDATE,-15)
    AND NOT EXISTS 
         (select 1 from table_2 b 
          where RTRIM(LTRIM(b.head)) = RTRIM(LTRIM(a.head))
          and b.effective_date = a.effective_date) )

Auf diese Weise kann die Abfrage viel schneller Ergebnisse zurückgeben, insbesondere wenn table_2 sehr klein ist oder auf die Zeilen über einen Index am Wirksamkeitsdatum oder Kopf zugegriffen werden kann.

PS. Wenn möglich, entfernen Sie die RTRIM(LTRIM())-Bits.

PPS. Es gibt immer noch keine Garantie, dass es in weniger als 8 Sekunden zurückkehrt. Das würde davon abhängen, wie groß table_1 ist, und Indizes auf type_of_action und/oder Effective_date.

Hinzugefügt:

Sie können mit dem Cursor durch

blättern
SELECT  RTRIM(LTRIM(A.HEAD)), A.EFFECTIVE_DATE,
    FROM   TABLE_1 A
    WHERE  A.TYPE_OF_ACTION='6'
    AND    A.EFFECTIVE_DATE >= ADD_MONTHS(SYSDATE,-15)

und Zeilen ignorieren, wenn sie zurückgegeben werden

    select 1 from table_2 b 
      where RTRIM(LTRIM(b.head)) = :1
      and b.effective_date = :1
      and rownum =1

Aber es würde sicherlich länger dauern, es vollständig auszuführen. Vielleicht um Größenordnungen länger (dh Stunden), je nachdem, wie lange jede Prüfung von table_2 dauert. Nicht genau sicher, welche Kriterien für die Abschaltung verwendet werden (Dauer des Aufrufs oder Dauer des offenen SQL-Cursors), daher könnte der äußere Cursor geschlossen werden. Und je nach Größe/Index/Inhalt von Tabelle_1 gibt der äußere Cursor möglicherweise immer noch nicht die ersten Zeilen innerhalb des Zeitrahmens zurück.

Wie viele Zeilen in Tabelle_1, Tabelle_2 und welche Indizes sind verfügbar?