createtablet0
(
sidintnotnull,
snamevarchar2(20)
)
tablespacetest;
--循环导入数据
declare
maxrecordsconstantint:=100000;
iint:=1;
begin
foriin1..maxrecordsloop
insertintot0values(i,'ocpyang'||i);
endloop;
dbms_output.put_line('成功录入数据!');
commit;
end;
/
createtablet1
as
selectsid,snamefromt0orderbysnamedesc;
createindexindex_t1ont1(sid);
createtablet2
as
selectsid,snamefromt0orderbysidasc;
createindexindex_t2ont2(sidasc);
--分析两张表及其索引
EXECDBMS_STATS.gather_table_stats(USER,'T1');
EXECDBMS_STATS.gather_table_stats(USER,'T2');
EXECDBMS_STATS.gather_index_stats(USER,'INDEX_T1');
EXECDBMS_STATS.gather_index_stats(USER,'INDEX_T2');
---比较同一个查询
setautottraceonlystat;
SELECT*FROMt1WHEREsidBETWEEN100AND120;
统计信息
----------------------------------------------------------
5recursivecalls
4dbblockgets
15consistentgets一致读
0physicalreads
540redosize
1240bytessentviaSQL*Nettoclient
530bytesreceivedviaSQL*Netfromclient
3SQL*Netroundtripsto/fromclient
0sorts(memory)
0sorts(disk)
21rowsprocessed
SELECT*FROMt2WHEREsidBETWEEN100AND120;
统计信息
----------------------------------------------------------
6recursivecalls
4dbblockgets
9consistentgets一致读
0physicalreads
540redosize
1240bytessentviaSQL*Nettoclient
530bytesreceivedviaSQL*Netfromclient
3SQL*Netroundtripsto/fromclient
0sorts(memory)
0sorts(disk)
21rowsprocessed
setautotraceoff;
由上得知,通过执行统计信息观察,t1表的查询一致读是15,而t2表的一致读只有9,尽然t1的一致读尽然是t2的1倍还多,
很奇怪,同样的表结构,同样的数据.
----分析原因:
select
b.table_name,
a.index_name,
b.num_rows,
b.blocks,
a.clustering_factorfrom
user_indexesa,user_tablesb
whereb.table_namein('T1','T2')
anda.table_name=b.table_name;
TABLE_NAMEINDEX_NAMENUM_ROWSBLOCKSCLUSTERING_FACTOR
---------------------------------------------------------
T1INDEX_T11000003301048
T2INDEX_T2100000330316
通过查询聚簇因子发现,两个表的聚簇因子差别很大,基于sid的索引在sid是顺序排列的表中,clustering_factor的值相差很大。
T1表中数据属于无序状态,这个时候的CLUSTERING_FACTOR比较接近NUM_ROWS,说明如果扫描整个表,
每次都要根据Index来读取相应行的RowID,这个时候的IO操作很多,自然检索时间会比较长。
T2表数据有序,CLUSTERING_FACTOR比较接近BLOCKS,说明相邻的数据在一个块中,减少了IO操作数量,
自然检索时间会大大降低.