Pour "forcer" Oracle à utiliser une analyse de plage d'index, utilisez simplement un indice d'optimisation INDEX_RS_ASC
. Par exemple :
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
L'accélération de l'exécution de votre requête dépend de nombreux facteurs, tels que la sélectivité de la valeur indexée ou l'ordre physique des lignes de votre table. Par exemple, si vous changez la requête en WHERE b BETWEEN 10 AND <xxx>
, les coûts suivants apparaissent dans les plans d'exécution sur ma machine :
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
Si vous modifiez très légèrement la requête pour non seulement sélectionner la colonne indexée b
, mais aussi d'autres colonnes non indexées, les coûts changent considérablement :
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