2016-06-29 14 views
0

Ich stehe bei der Verwendung von SQL-Abfragen mit Aggregationsfunktionen einigen Leistungsproblemen gegenüber. Daher dachte ich, es wäre eine gute Idee zu verstehen, wie die Indexerstellung genau funktioniert. Ich kam eine Sache, über konnte ich nicht verstehen: Was ist der Unterschied zwischen diesen beiden Schöpfungs Richtlinien ist ?:Oracle Indexerstellungssyntax

1.)CREATE INDEX FIELD1_INDEX ON TABLE1 (FIELD1) ONLINE TABLESPACE XXX; 
    CREATE INDEX timeofrequest_INDEX ON TABLE1 (timeofrequest) ONLINE TABLESPACE XXX; 

2.)CREATE INDEX COMBINED_INDEX ON TABLE1 (FIELD1, FIELD2) ONLINE TABLESPACE XXX; 

Der Grund, warum ich gefragt habe, ist, dass ich eine Abfrage wie haben:

SELECT SUM(field1) FROM table1 WHERE timeofrequest BETWEEN 1 AND 2; 

Tabelle 1 enthält viele Daten, sodass diese Abfrage mehr als 20 Sekunden benötigt, um fertig zu sein. Um eine lange Laufzeit zu vermeiden, habe ich versucht, mit Ansatz 1 zu gehen und einen Index für jedes betroffene Feld zu erstellen. In der Tat ist es immer noch zu langsam. Bei der Analyse des Ausführungsplans sehe ich, dass der Index timeofrequest verwendet wird, aber nicht der für field1. Sollte es helfen, wenn ich eine Kombination mit einer einzigen Aussage erstelle? Macht es einen Unterschied?

Antwort

0

Ihre ersten beiden Indizes unterscheiden sich also insofern von Ihrem dritten Index, als die ersten beiden nur eine SINGLE-Spalte für den Index verwenden. Ihr dritter Index besteht aus zwei verschiedenen Spalten für Ihren Index, aber der dritte kann weiterhin verwendet werden, auch wenn Sie nur die erste Spalte im Index angeben ... dies wird als zusammengesetzter Index bezeichnet. Oracle kann wirklich nur einen SINGLE-Index innerhalb einer einzelnen Abfrageanweisung verwenden, und das CBO wird die beste zu verwendende Option herausfinden.

In Ihrem ersten Beispiel haben Sie zwei Indizes gegen einzelne Spalten. Ihr zweites Beispiel ist ein SINGLE-Index mit zwei Spalten. Ihr erstes Beispiel verwendet NUR das eine oder das andere, aber nicht beide für eine bestimmte einzelne SELECT-Anweisung (CBO entscheidet anhand Ihrer Abfrage, was zu verwenden ist).

Beispiel:

SELECT SUM(field1) FROM table1 WHERE timeofrequest BETWEEN 1 AND 2; 

Dieser wird versuchen, nur den Index, den Sie gegen timeofrequest gesetzt haben zu verwenden. In der Tat wird es versuchen, einen Entfernungsscan durchzuführen.

Beispiel für die zweiten Index:

SELECT SUM(field1) FROM table1 WHERE FIELD1 = 'x'; 

Angenommen, Sie keinen Index gegen nur ‚FIELD1‘ haben, das das COMBINED_INDEX nutzen würden Sie an den richtigen Stelle, und alle Datensätze pro dem ersten Feld des Index holen .

Wenn Sie hatte:

SELECT SUM(field1) FROM table1 WHERE FIELD2 = 'y'; 

Dies würde die combined_index NICHT verwenden, da der Index zum ersten Mal gebaut wird FIELD1 mit um, dann FIELD2.

Wenn Sie hatte:

SELECT SUM(field1) FROM table1 WHERE FIELD1 = 'x' and FIELD2 = 'y'; 

Dies würde die COMBINED_INDEX noch nutzen, aber hier bieten Sie eine feinere Ebene der Granularität. Es würde den vollen Index (field1 und field2 ...) verwenden, um Ihre Reihe (n) viel schneller zurückzugeben. Warum ist das nützlich? Nun, es ist möglich, dass Sie einen Index für FIELD1 haben, und die einfache Suche auf ONLY field1 würde immer noch viele Tausende (oder Zehntausende oder Millionen ...) von Datensätzen ergeben, so dass Sie eine weitere Spalte als Teil des Indexes bereitstellen können wird einfach helfen, die benötigten Datensätze zu zielen ... was wiederum zu einer höheren Selektivität führt.

WICHTIGER Hinweis! Denken Sie daran, dass das CBO den besten Ansatz ermittelt. Wenn Sie eine schlechte Kardinalität haben (Forschungstabelle Kardinalität ...) auf Ihrem Tisch für diese Spalte, ist es möglich, dass Sie den Index überhaupt nicht verwenden, und ein vollständiger Tabellenscan wäre laut CBO besser. Wenn Sie eine hohe Kardinalität haben und den Index immer noch nicht verwenden, müssen Sie möglicherweise Ihre Tabelle und die darin enthaltenen Indizes analysieren und dann Ihren EXPLAIN-Plan erneut ausführen, um zu sehen, ob Sie neue Ergebnisse erhalten. Es ist auch möglich, dass Sie eine geringe Kardinalität haben, weil sich so viele Daten in der Tabelle ändern und nicht erst kürzlich analysiert wurden. Analysieren Sie Ihre Tabelle/Indizes ist eine ziemlich wichtige Sache zu tun und kann leicht übersehen werden. Bei mehreren Gelegenheiten habe ich Fälle gefunden, in denen ich arbeite, die einfach die Tabelle neu analysieren und/oder Indizes, die unglaubliche Verbesserungen gemacht haben.

Bitte überprüfen Sie die Analyse von Tabellen und die Verwendung von DBMS_STATS.

https://docs.oracle.com/cd/B28359_01/appdev.111/b28419/d_stats.htm

auch andere Lösung, dass, wenn Sie große Datenmengen haben, und Ihr „Zeit der Anfrage“ -Spalte wirklich nur eine geringe unterschiedliche Menge von Werten (vielleicht in der Tabelle von 50 Millionen Datensatz gibt es nur 20 verschiedene Werte ..), dann können Sie eine partitionierte Tabelle einrichten und Indizes von dort bereitstellen. Es würde die Abfrageleistungszeiten erheblich verbessern.

+0

Vielen Dank, ich schätze Ihre Hilfe –