Die meisten Unternehmensdatenbanken, einschließlich Oracle, verwenden einen kostenbasierten Optimierer, um den geeigneten Abfrageplan für eine bestimmte SQL-Anweisung zu bestimmen. Das bedeutet, dass der Optimierer Informationen über die Daten verwendet, um zu bestimmen, wie eine Abfrage ausgeführt wird, anstatt sich auf Regeln zu verlassen (das tat der ältere regelbasierte Optimierer).
Stellen Sie sich zum Beispiel eine Tabelle für eine einfache Bug-Tracking-Anwendung vor
CREATE TABLE issues (
issue_id number primary key,
issue_text clob,
issue_status varchar2(10)
);
CREATE INDEX idx_issue_status
ON issues( issue_status );
Wenn ich ein großes Unternehmen bin, habe ich vielleicht 1 Million Zeilen in dieser Tabelle. Davon haben 100 einen issue_status
von ACTIVE haben 10.000 einen issue_status
QUEUED und 989.900 haben den Status COMPLETE. Wenn ich eine Abfrage für die Tabelle ausführen möchte, um meine aktiven Vorgänge zu finden
SELECT *
FROM issues
WHERE issue_status = 'ACTIVE'
der Optimierer hat die Wahl. Es kann entweder den Index auf issue_status
verwenden und führen Sie dann eine Einzelzeilensuche in der Tabelle für jede Zeile im Index durch, die übereinstimmt, oder führen Sie einen Tabellenscan der issues
durch Tisch. Welcher Plan effizienter ist, hängt von den Daten in der Tabelle ab. Wenn Oracle erwartet, dass die Abfrage einen kleinen Teil der Daten in der Tabelle zurückgibt, wäre die Verwendung des Index effizienter. Wenn Oracle erwartet, dass die Abfrage einen erheblichen Teil der Daten in der Tabelle zurückgibt, wäre ein Tabellenscan effizienter.
DBMS_STATS.GATHER_TABLE_STATS
sammelt die Statistiken, die es Oracle ermöglichen, diese Feststellung zu treffen. Es teilt Oracle mit, dass es ungefähr 1 Million Zeilen in der Tabelle gibt, dass es 3 unterschiedliche Werte für den issue_status
gibt Spalte, und dass die Daten ungleichmäßig verteilt sind. Oracle weiß also, dass es einen Index für die Abfrage verwenden muss, um alle aktiven Probleme zu finden. Aber es weiß das auch, wenn Sie sich umdrehen und versuchen, nach allen geschlossenen Problemen zu suchen
SELECT *
FROM issues
WHERE issue_status = 'CLOSED'
dass es effizienter ist, einen Tabellenscan durchzuführen.
Durch das Sammeln von Statistiken können sich die Abfragepläne im Laufe der Zeit ändern, wenn sich die Datenmengen und Datenverteilungen ändern. Wenn Sie den Issue-Tracker zum ersten Mal installieren, werden Sie nur sehr wenige COMPLETED-Probleme und mehr ACTIVE- und QUEUED-Probleme haben. Im Laufe der Zeit steigt die Zahl der ABGESCHLOSSENEN Ausgaben viel schneller an. Wenn Sie mehr Zeilen in der Tabelle erhalten und sich der relative Anteil dieser Zeilen in den verschiedenen Status ändert, ändern sich die Abfragepläne, sodass Sie im Idealfall immer den effizientesten Plan erhalten.