3 Stimmen

Daten effektiv auswählen sql

Ich habe eine sehr große Tabelle mit über 1000 Datensätzen und 200 Spalten. Wenn ich versuche, Datensätze abzurufen, die einigen Kriterien in der WHERE Klausel mit SELECT Aussage braucht es viel Zeit. Meistens möchte ich aber nur einen einzigen Datensatz auswählen, der den Kriterien in der Anweisung WHERE Klausel und nicht alle Datensätze.

Ich denke, es sollte eine Möglichkeit geben, nur einen einzigen Datensatz auszuwählen und die Suche zu beenden, was die Abrufzeit minimieren würde. Ich habe versucht ROWNUM=1 en el WHERE Klausel, aber es hat nicht wirklich funktioniert, weil ich vermute, dass die Maschine immer noch alle Datensätze überprüft, selbst nachdem sie den ersten Datensatz gefunden hat, der mit der WHERE Kriterien. Gibt es eine Möglichkeit zur Optimierung für den Fall, dass ich nur einige wenige Datensätze auswählen möchte?
Vielen Dank im Voraus.

Bearbeiten:

Ich verwende Oracle 10g. Die Abfrage sieht wie folgt aus,

Select * 
from Really_Big_table 
where column1 is NOT NULL 
and column2 is NOT NULL 
and rownum=1;

Dies scheint langsamer zu funktionieren als die Version ohne rownum=1;

1voto

Simon Nickerson Punkte 40349

rownum ist, was Sie wollen, aber Sie müssen Ihre Hauptabfrage als Unterabfrage durchführen.

Wenn Ihre ursprüngliche Anfrage zum Beispiel lautet:

  SELECT co1, col2
    FROM table
    WHERE condition

dann sollten Sie versuchen

  SELECT *
  FROM (
    SELECT col1, col2
      FROM table
      WHERE condition
  ) WHERE rownum <= 1

Siehe http://www.oracle.com/technology/oramag/oracle/06-sep/o56asktom.html für Einzelheiten darüber, wie rownum arbeitet in Oracle.

1voto

Fenton Punkte 221749

1.000 Datensätze sind keine große Menge an Daten in einer Tabelle. 200 Spalten sind eine recht breite Tabelle. Aus diesem Grund würde ich vermuten, dass Sie es nicht mit einer wirklich großen Tabelle zu tun haben - ich habe Abfragen über Millionen von Zeilen ohne Probleme durchgeführt.

Hier ist ein kleines Experiment... wie lange dauert die Ausführung im Vergleich zur "SELECT *"-Abfrage?

SELECT
    Really_Big_table.Id
FROM
    Really_Big_table
WHERE 
    column1 IS NOT NULL
AND
    column2 IS NOT NULL
AND
    rownum=1;

0voto

Oded Punkte 475566

In SQL würde der größte Teil der Optimierung in Form eines Index für die Tabelle erfolgen (wobei Sie die Spalten indizieren würden, die in der WHERE y ORDER BY Spalten als grobe Orientierung).

Sie haben nicht angegeben, welche SQL-Datenbank Sie verwenden, daher kann ich Ihnen keine gute Quelle nennen.

Hier ist eine Einführung in Indizes bei Oracle.

Hier ein weiterer Lehrgang.

Was die Abfragen betrifft, so sollten Sie immer die Spalten angeben, die Sie zurückgeben, und keine pauschalen * .

0voto

vodkhang Punkte 18481

Ein Beispiel finden Sie hier: Sie können mehr sehen ici

SELECT ename, sal 
FROM ( SELECT ename, sal, RANK() OVER (ORDER BY sal DESC) sal_rank
              FROM emp ) 
WHERE sal_rank <= 1;

Sie müssen auch einige Spaltenindizierungen für die Spalten in der WHERE-Klausel vornehmen

0voto

Vincent Malgrat Punkte 65127

Es sollte nicht viel Zeit in Anspruch nehmen, eine Tabelle mit 1000 Zeilen abzufragen. Es gibt jedoch Ausnahmen. Prüfen Sie, ob einer der folgenden Fälle auf Sie zutrifft:

1. Viele Zeilen wurden gelöscht

Die Tabelle hatte in der Vergangenheit eine große Anzahl von Zeilen. Seit der Hochwassermarke ( HWM ) ist immer noch hoch (Löschen wird ihn nicht senken) und FULL TABLE SCAN alle Daten bis zur Hochwassermarke zu lesen, kann es sehr lange dauern, bis Ergebnisse zurückgegeben werden, auch wenn die Tabelle jetzt fast leer ist.

Analysieren Sie Ihre Tabelle ( dbms_stats.gather_table_stats('<owner>','<table>') ) und vergleichen Sie den von den Zeilen tatsächlich belegten Platz (Speicherplatz auf der Festplatte) mit dem effektiven Platz (Daten), zum Beispiel:

SELECT t.avg_row_len * t.num_rows data_bytes, 
       (t.blocks - t.empty_blocks) * ts.block_size bytes_used
  FROM user_tables t
  JOIN user_tablespaces ts ON t.tablespace_name = ts.tablespace_name
 WHERE t.table_name = '<your_table>';

Sie müssen den Overhead der Zeilen und Blöcke sowie den für die Aktualisierung reservierten Platz (PCT_FREE) berücksichtigen. Wenn Sie feststellen, dass Sie viel mehr Speicherplatz als erforderlich verwenden (der typische Overhead liegt unter 30 %, YMMV), sollten Sie den HWM zurücksetzen:

  • ALTER TABLE <your_table> MOVE; und bauen Sie dann INDEX neu auf ( ALTER INDEX <index> REBUILD ), vergessen Sie nicht, anschließend die Statistiken zu sammeln.
  • verwenden. DBMS_REDEFINITION

2. Die Tabelle hat sehr große Spalten

Prüfen Sie, ob Sie Spalten des Datentyps LOB, CLOB, LONG (irk), etc. haben. Daten über 4000 Bytes in einer dieser Spalten werden außerhalb der Zeile (in einem separaten Segment) gespeichert, was bedeutet, dass Sie, wenn Sie diese Spalten nicht auswählen, nur die anderen kleineren Spalten abfragen.

Wenn dies der Fall ist, verwenden Sie nicht SELECT * . Entweder benötigen Sie die Daten in den großen Spalten nicht oder Sie verwenden SELECT rowid und führen dann eine zweite Abfrage durch: SELECT * WHERE rowid = <rowid> .

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X