纸上得来终觉浅,绝知此事要躬行
索引学习五--物理组织对索引访问的影响
上一篇 /
下一篇 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: