纸上得来终觉浅,绝知此事要躬行

索引学习五--物理组织对索引访问的影响

上一篇 / 下一篇  2008-05-26 10:45:50 / 个人分类:读书笔记

1. 创建2个测试表,一个表的数据按照顺序存放,另一个随机存放。

sys@TEST>createtable colocated(x int,y varchar2(80));
 
Table created.
 
sys@TEST>begin
  2  for i in 1 .. 100000
  3  loop
  4  insert into colocated(x,y)
  5  values(i,rpad(dbms_random.random,75,'*'));
  6  end loop;
  7  end;
  8  /
 
PL/SQL procedure successfully completed.
 
sys@TEST>altertable colocated
  2  add constraint colocated_pk
  3  primary key(x);
 
Table altered.
 
sys@TEST>execdbms_stats.gather_table_stats(user,'COLOCATED',cascade=>true);
 
PL/SQL procedure successfully completed.
 
sys@TEST>createtable disorganized
  2  as select x,y
  3  from colocated
  4  order by y;
 
Table created.
 
sys@TEST>altertable disorganized
  2  add constraints disorganized_pk
  3  primary key(x);
 
Table altered.

sys@TEST>execdbms_stats.gather_table_stats(user,'DISORGANIZED',cascade=>true);
 
PL/SQL procedure successfully completed.

2.分别对这两个表进行条件查询。

sys@TEST>setautotrace traceonly statistics;
sys@TEST>select* from colocated where x between 20000 and 40000;
 
20001 rows selected.
 
 
Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
       2482  consistent gets
          0  physical reads
          0  redo size
    1805701  bytes sent via SQL*Net to client
      15166  bytes received via SQL*Net from client
       1335  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
      20001  rows processed
 
sys@TEST>select* from  DISORGANIZED where x between 20000 and 40000;
 
20001 rows selected.
 
 
Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
       2518  consistent gets
          0  physical reads
          0  redo size
    1805701  bytes sent via SQL*Net to client
      15166  bytes received via SQL*Net from client
       1335  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
      20001  rows processed

发现2个查询的consistent gets差不多,查看执行计划,

sys@TEST>select* from colocated where x between 20000 and 40000;
 
Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT ptimizer=CHOOSE (Cost=116 Card=20002 Bytes
          =1600160)
 
   1    0   TABLE ACCESS (FULL) OF 'COLOCATED' (Cost=116 Card=20002 By
          tes=1600160)
 

sys@TEST>select* from  DISORGANIZED where x between 20000 and 40000;
 
Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT ptimizer=CHOOSE (Cost=116 Card=20002 Bytes
          =1600160)
 
   1    0   TABLE ACCESS (FULL) OF 'DISORGANIZED' (Cost=116 Card=20002
           Bytes=1600160)

 

原来均使用了全表扫描,强制使用索引进行查询:

sys@TEST>select/*+ index(colocated colocated_pk) */* from colocated where x between 20000 and 40000;
 
20001 rows selected.
 
 
Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
       2899  consistent gets
          0  physical reads
          0  redo size
    1805701  bytes sent via SQL*Net to client
      15166  bytes received via SQL*Net from client
       1335  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
      20001  rows processed


 sys@TEST>select/*+ index(disorganized disorganized_pk) */* from disorganized where x between 20000 and 40000;
 
20001 rows selected.
 
 
Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
      21357  consistent gets
          0  physical reads
          0  redo size
    1805701  bytes sent via SQL*Net to client
      15166  bytes received via SQL*Net from client
       1335  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
      20001  rows processed

可见,这一次查询,二者的consistent gets差别明显,证明了物理存储布局对于索引访问的影响之大。再进一步分析这两种存储布局情况下的索引结构,可以发现,二者的区别在与聚簇因子不同。

sys@TEST>l
  1   select a.index_name,b.num_rows,b.blocks,a.clustering_factor
  2   from user_indexes a,user_tables b
  3  where index_name in('COLOCATED_PK','DISORGANIZED_PK')
  4*  and a.table_name=b.table_name
sys@TEST>/
 
INDEX_NAME                       NUM_ROWS     BLOCKS CLUSTERING_FACTOR
------------------------------ ---------- ---------- -----------------
COLOCATED_PK                       100000       1191              1190
DISORGANIZED_PK                    100000       1191             99914


       聚簇因子的值反映了表中行的有序程度,如果这个值与块数接近,说明表相当有序,在这种情况下,同一个叶子块的索引条目可能指向了同一个数据块上的行。如果这个值与行数接近,表的次序可能就是非常随机的,同一个叶子块上的索引条目不太可能指向同一个数据块上的行。

      通过这个例子也可以发现,oracle基于CBO的优化器确实精准,当它认为使用全表扫描消耗代价最小时,执行计划就会选择全表扫描,而不是使用索引,显然这比基于规则的方式更加先进。


TAG:

 

评分:0

我来说两句

显示全部

:loveliness: :handshake :victory: :funk: :time: :kiss: :call: :hug: :lol :'( :Q :L ;P :$ :P :o :@ :D :( :)

日历

« 2008-09-07  
 123456
78910111213
14151617181920
21222324252627
282930    

数据统计

  • 访问量: 1573
  • 日志数: 67
  • 图片数: 2
  • 影音数: 1
  • 建立时间: 2008-02-29
  • 更新时间: 2008-09-06

RSS订阅

Open Toolbar