2016-10-20 3 views
0

Ich versuche, eine Abfrage zu verbessern. Ich habe einen Ticket-Datensatz geöffnet. Jedes Ticket hat unterschiedliche Zeilen, jede Zeile enthält eine Aktualisierung des Tickets. Es gibt ein Feld (dt_update), das sich in jeder Zeile unterscheidet.Oracle Tuning für Abfrage mit Abfrage annidate

Ich habe diese Indizes in der st_remedy_full_light.
IDX_ASSIGNMENT (AUFGABE)
IDX_REMEDY_INC_ID (REMEDY_INC_ID)
IDX_REMDULL_LIGHT_DTUPD (DT_UPDATE)

Nun wird die Abfrage in 8 Sekunden ausgeführt. Ist hoch für mich.

WITH last_ticket AS 
    (SELECT * 
    FROM st_remedy_full_light a 
    WHERE a.dt_update IN 
    (SELECT MAX(dt_update) 
     FROM st_remedy_full_light 
     WHERE remedy_inc_id = a.remedy_inc_id 
    ) 
) 
SELECT remedy_inc_id, ASSIGNMENT FROM last_ticket 

Das ist der Plan Explain Plan Wie ich könnte diese Abfrage zu verbessern?

P.S. Dies ist nur ein Teil einer großen Abfrage

Zusätzliche Informationen: - Die Tabelle st_remedy_full_light 529,507 Reihen

+0

Können mehrere 'st_remedy_full_light' mit demselben 'dt_update' pro 'remedy_inc_id' sein? –

+0

ein Index auf (Abhilfe_inc_id, dt_update) - oder möglicherweise sogar (Abhilfe_inc_id, dt_update, Zuweisung) - sollte Ihnen helfen, wenn Sie die Unterabfrage zu Tony Andrews nicht ändern wollen/können. I.e. Ein einzelner Index mit mehreren Spalten anstelle eines Index für jede Spalte - Oracle kann nur einen dieser einzelnen Spaltenindizes für die Abfrage verwenden. Es können nicht alle drei Spalten verwendet werden, obwohl Sie alle drei Spalten in Ihrer Spalte verwenden Abfrage. Ein solcher Index würde wahrscheinlich auch Tony Andrews vorgeschlagene Abfrage helfen. – Boneist

+0

@EvgeniyK. nicht nur remedy_inc_id haben mehr dt_update, aber nicht die andere. – vecio88

Antwort

2

Sie könnten enthalten versuchen:

WITH last_ticket AS 
    (SELECT remedy_inc_id, ASSIGNMENT, 
      rank() over (partition by remedy_inc_id order by dt_update desc) rn 
    FROM st_remedy_full_light a 
) 
SELECT remedy_inc_id, ASSIGNMENT FROM last_ticket 
where rn = 1; 
+0

Hallo Tony, danke für Ihre Antwort ... Leider habe ich diese Lösung verwendet, aber ist seltsamerweise langsamer als meine Lösung. – vecio88

+0

Können Sie bitte mehr Details darüber, warum diese Abfrage im Vergleich zu ursprünglichen schnell laufen wird. – NzGuy

+0

@NzGuy Ich würde _expect_ es zu _probably_ schneller, da es nicht Hash-Beitritt 'last_ticket' zu sich selbst sagen müssen. –

1

Die beste Alternative Abfrage, die auch viel einfacher, auszuführen, ist dies:

select remedy_inc_id 
    , max(assignment) keep (dense_rank last order by dt_update) 
    from st_remedy_full_light 
group by remedy_inc_id 

dies nur eine vollständige Tabellensuche verwenden und eine (hash/sort) Gruppe, tritt keine Selbst.

Machen Sie sich keine Gedanken über indizierten Zugriff, da Sie hier wahrscheinlich einen vollständigen Tabellenscan finden. Es sei denn, die Tabelle ist wirklich breit und ein zusammengesetzter Index für alle verwendeten Spalten (Abhilfe_inc_id, dt_update, Zuweisung) wäre wesentlich schneller zu lesen als die Tabelle.