sql >> Databasteknik >  >> RDS >> Oracle

Hur tvingar man Oracle att använda index range scan?

För att "tvinga" Oracle att använda en skanning av indexintervall, använd helt enkelt en optimeringstips INDEX_RS_ASC . Till exempel:

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

Huruvida detta kommer att göra att din fråga faktiskt körs snabbare beror på många faktorer som selektiviteten för det indexerade värdet eller den fysiska ordningen på raderna i tabellen. Om du till exempel ändrar frågan till WHERE b BETWEEN 10 AND <xxx> , följande kostnader visas i exekveringsplanerna på min dator:

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

Om du ändrar frågan väldigt lite för att inte bara välja den indexerade kolumnen b , men även andra, icke-indexkolumner, förändras kostnaderna dramatiskt:

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


  1. Två dubbletter av index med samma kolumner

  2. Välj de första 150 raderna, sedan de nästa 150 och så vidare?

  3. Hur man arbetar med javax.persistence.sql-load-script-source?

  4. Att infoga nationella tecken i en oracle NCHAR eller NVARCHAR kolumn fungerar inte