Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Wie kann man Oracle zwingen, den Indexbereichsscan zu verwenden?

Um Oracle zu „zwingen“, einen Indexbereichsscan zu verwenden, verwenden Sie einfach einen Optimierungshinweis INDEX_RS_ASC . Zum Beispiel:

CREATE TABLE mytable (a NUMBER NOT NULL, b NUMBER NOT NULL, c CHAR(10)) NOLOGGING;

INSERT /*+ APPEND */ INTO mytable(a,b,c) 
SELECT level, mod(level,100)+1, 'a'  FROM dual CONNECT BY level <= 1E6;

CREATE INDEX myindex_ba ON mytable(b, a);
EXECUTE dbms_stats.gather_table_stats(NULL,'mytable');

SELECT /*+ FULL(m)         */ b FROM mytable m WHERE b=10; -- full table scan
SELECT /*+ INDEX_RS_ASC(m) */ b FROM mytable m WHERE b=10; -- index range scan
SELECT /*+ INDEX_FFS(m)    */ b FROM mytable m WHERE b=10; -- index fast full scan

Ob Ihre Abfrage dadurch tatsächlich schneller ausgeführt wird, hängt von vielen Faktoren wie der Selektivität des indizierten Werts oder der physischen Reihenfolge der Zeilen in Ihrer Tabelle ab. Zum Beispiel, wenn Sie die Abfrage in WHERE b BETWEEN 10 AND <xxx> ändern , erscheinen die folgenden Kosten in den Ausführungsplänen auf meinem Computer:

b BETWEEN 10 AND    10     20      40     80
FULL               749    750     751    752
INDEX_RS_ASC        29    325     865   1943
INDEX_FFS          597    598     599    601

Wenn Sie die Abfrage geringfügig ändern, um nicht nur die indizierte Spalte b auszuwählen , aber auch andere Nicht-Index-Spalten ändern sich die Kosten dramatisch:

b BETWEEN 10 AND    10     20      40     80
FULL               749    750     751    754
INDEX_RS_ASC      3352  40540  108215 243563
INDEX_FFS         3352  40540  108215 243563