2017-05-25 4 views
0

Ich habe Millionen Datensatz in der Datenbanktabelle mit Konto Nr, Adresse und viele weitere Spalten. Ich möchte 100 Zeilen in der Reihenfolge sortieren, ich habe rownum dafür verwendet, aber die Abfrage dauert sehr lange, da sie die gesamte Tabelle zuerst in sortierter Reihenfolge durchsucht und dann das rownum anwendet.SQL-Tuning, lange laufende Abfrage + rownum

Was ist die Lösung zur Minimierung der Abfrage Ausführungszeit?

Zum Beispiel:

select * 
from 
    (select 
     acc_no, address 
    from 
     customer 
    order by 
     acc_no desc) 
where 
    ROWNUM <= 100; 
+0

Haben Sie den Index für die Kundentabelle definiert? – Sumit

+0

Da Sumit sagt, dass Sie einen Index haben sollten, nehme ich an acc_no ist einzigartig? Wenn es nicht Ihr Primärschlüssel ist, sollte es zumindest im Index enthalten sein – MarkD

+1

Für welches RDBMS ist das? Bitte fügen Sie ein Tag hinzu, um anzugeben, ob Sie 'mysql',' postgresql', 'sql-server',' oracle' oder 'db2' verwenden - oder etwas ganz anderes. –

Antwort

2

Aus den Erfahrungen der Vergangenheit fand ich, dass die TOP besten für dieses Szenario funktioniert.

Auch sollten Sie immer die Spalten auswählen, die Sie nur brauchen, und vermeiden Sie die ganze Karte mit (*)

SELECT TOP 100 [acc_no], [address] FROM [customer] ORDER BY [acc_no] DESC 

Nützliche Ressourcen zu TOP, LIMIT und sogar ROWNUM.

0

Stellen Sie sicher, dass Index auf acc_no Spalte.

  1. Wenn auf acc_no bereits ein Index vorhanden ist, überprüfen Sie, ob dieser während der Abfrageausführung verwendet wird oder nicht, indem Sie den Abfrageausführungsplan überprüfen.

Um einen neuen Index, wenn nicht vorhanden, verwenden Sie unter Abfrage zu erstellen:

Create index idx1 on customer(acc_no); -- If acc_no is not unique 
Create unique index idx1 on customer(acc_no); -- If acc_no is unique. Note: Unique index is faster. 
  1. Wenn in Planausgabe erklären Sie "Full-Table-Scan" zu sehen, die es dann ist ein Fall, dass der Optimierer den Index nicht verwendet.

mit einem Hauch Versuchen Sie zuerst:

select /*+ index(idx1) */ * from 
(select 
    acc_no, address 
from 
    customer 
order by 
    acc_no desc) 
where 
ROWNUM <= 100; 
  1. Wenn die Abfrage mit Hinweis oben zurückgegebenen Ergebnisse schnell, dann müssen Sie prüfen, warum Optimierer Ihr Index absichtlich ignoriert . Ein möglicher Grund dafür sind veraltete Statistiken. Aktualisieren Sie die Statistiken.

Hoffe, das hilft.

+0

Dank @Shinchan – Kamal

0

Ziehen Sie in Betracht, Ihre obersten Kontonummern in einer inneren Abfrage/In-line-Ansicht abzurufen, sodass Sie nur die Verknüpfungen für diese 100 Kundendatensätze ausführen. Andernfalls könnten Sie alle Joins in den Millionen + Zeilen durchführen und dann die Millionen + Ergebnisse sortieren, um die Top 100 zu erhalten. So etwas könnte funktionieren.

select ..... 
    from customer 
    where customer.acc_no in (select acc_no from 
         (select inner_cust.acc_no 
         from customer inner_cust 
         order by inner_cust.acc_no desc 
         ) 
        where rownum <= 100) 
     and ... 

Oder, wenn Sie 12C verwenden Sie diese FETCH FIRST 100 ROWS ONLY

select ..... 
    from customer 
    where customer.acc_no in (select inner_cust.acc_no 
           from customer inner_cust 
           order by inner_cust.acc_no desc 
           fetch first 100 rows only 
          ) 
     and ... 
0

geben das Ergebnis innerhalb von 100 ms, aber stellen Sie sicher, dass es Index auf der Spalte ACC_NO verwenden können. Es kann auch ein kombinierter Index für ACC_NO + andere Spalten vorhanden sein, aber ACC_NO muss sich an der ersten Position im Index befinden. Sie müssen "Bereichsscan" im Ausführungsplan sehen. Nicht "vollständiger Tabellenscan", nicht "Scan überspringen".Sie können wahrscheinlich geschachtelte Schleifen im Ausführungsplan sehen (die ADDRESSes aus der Tabelle holen). Sie können die Geschwindigkeit noch weiter verbessern, indem Sie einen kombinierten Index für ACC_NO, ADDRESS (in dieser Reihenfolge) erstellen. In diesem Fall muss die Oracle-Engine die Tabelle überhaupt nicht lesen, da alle Informationen im Index enthalten sind. Sie können es im Ausführungsplan vergleichen.

select top 100 acc_no, address 
    from customer 
    order by acc_no desc 
+0

funktioniert "top" in Oracle DB – Kamal

+0

Ich bin mir nicht sicher, in diesem Fall ist Ihr SQL korrekt, nur kümmern sich um die ordnungsgemäße Einrichtung der Indizes –