Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Using an index degrades query performance if it results in <em>more</em> disk IO compared to querying the table with an index.</p> <p>This can be demonstrated with a simple table:</p> <pre><code>create table tq84_ix_test ( a number(15) primary key, b varchar2(20), c number(1) ); </code></pre> <p>The following block fills 1 Million records into this table. Every 250th record is filled with a <code>rare value</code> in column b while all the others are filled with <code>frequent value</code>:</p> <pre><code>declare rows_inserted number := 0; begin while rows_inserted &lt; 1000000 loop if mod(rows_inserted, 250) = 0 then insert into tq84_ix_test values ( -1 * rows_inserted, 'rare value', 1); rows_inserted := rows_inserted + 1; else begin insert into tq84_ix_test values ( trunc(dbms_random.value(1, 1e15)), 'frequent value', trunc(dbms_random.value(0,2)) ); rows_inserted := rows_inserted + 1; exception when dup_val_on_index then null; end; end if; end loop; end; / </code></pre> <p>An index is put on the column</p> <pre><code>create index tq84_index on tq84_ix_test (b); </code></pre> <p>The same query, but once with index and once without index, differ in performance. Check it out for yourself:</p> <pre><code>set timing on select /*+ no_index(tq84_ix_test) */ sum(c) from tq84_ix_test where b = 'frequent value'; select /*+ index(tq84_ix_test tq84_index) */ sum(c) from tq84_ix_test where b = 'frequent value'; </code></pre> <p>Why is it? In the case without the index, <em>all</em> database blocks are read, in sequential order. Usually, this is costly and therefore considered bad. In normal situation, with an index, such a "full table scan" can be reduced to reading say 2 to 5 index database blocks plus reading the one database block that contains the record that the index points to. With the example here, it is different altogether: the entire index is read and for (almost) each entry in the index, a database block is read, too. So, not only is the entire table read, but also the index. Note, that this behaviour would differ if <code>c</code> were also in the index because in that case Oracle could choose to get the value of <code>c</code> from the index instead of going the detour to the table.</p> <p>So, to generalize the issue: if the index does not pick few records then it might be beneficial to not use it.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload