您的位置:首页 > 其它

普通表索引,分区表局部索引和分区表的全局索引分区的效率对比测试

2011-03-08 11:06 501 查看
首先创建一个大表:

create table big_table
as
select rownum id, a.*
from all_objects a
where 1=0
/
alter table big_table nologging;

declare
l_cnt number;
l_rows number := &1;
begin
insert /*+ append */
into big_table
select rownum, a.*
from all_objects a;

l_cnt := sql%rowcount;

commit;

while (l_cnt < l_rows)
loop
insert /*+ APPEND */ into big_table
select rownum+l_cnt,
OWNER, OBJECT_NAME, SUBOBJECT_NAME,
OBJECT_ID, DATA_OBJECT_ID,
OBJECT_TYPE, CREATED, LAST_DDL_TIME,
TIMESTAMP, STATUS, TEMPORARY,
GENERATED, SECONDARY
from big_table
where rownum <= l_rows-l_cnt;
l_cnt := l_cnt + sql%rowcount;
commit;
end loop;
end;
/

alter table big_table add constraint
big_table_pk primary key(id)
/

begin
dbms_stats.gather_table_stats
( ownname => user,
tabname => 'BIG_TABLE',
method_opt => 'for all indexed columns',
cascade => TRUE );
end;
/

在本次测试中我创建了200万行记录。

然后创建一个Hash分区表:

create table big_table_hashed nologging
partition by hash(object_id) partitions 10
as
select * from big_table;

为两张表对owner字段创建索引:

create index big_idx1 on big_table(owner);
create index big_hash_idx1 on big_table_hashed(owner) LOCAL;

analyze table big_table compute statistics for table;
analyze table big_table compute statistics for all indexes;
analyze table big_table compute statistics for all indexed columns;
analyze table big_table_hashed compute statistics for table;
analyze table big_table_hashed compute statistics for all indexes;
analyze table big_table_hashed compute statistics for all indexed columns;

请注意:这个索引并非分区键。

使用如下测试脚本对比二者效率:

variable own varchar2(100);
declare
dumy big_table_hashed%rowtype;
begin
for i in 1..100
loop
for x in ( select distinct owner from big_table_hashed)
loop
:own := x.owner;
select * into dumy from big_table_hashed where owner = :own and rownum =1;
end loop;
end loop;
end;
/

variable own varchar2(100);
declare
dumy big_table%rowtype;
begin
for i in 1..100
loop
for x in ( select distinct owner from big_table)
loop
:own := x.owner;
select * into dumy from big_table where owner = :own and rownum =1;
end loop;
end loop;
end;
/
使用tkprof工具查看效率对比结果:

hash分区表:

SELECT *
FROM
BIG_TABLE_HASHED WHERE OWNER = :B1 AND ROWNUM =1

call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 2100 0.32 0.40 0 0 0 0
Fetch 2100 5.54 6.56 3720 1154600 0 2100
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 4201 5.87 6.97 3720 1154600 0 2100

普通表:

SELECT *
FROM
BIG_TABLE WHERE OWNER = :B1 AND ROWNUM =1

call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 2100 0.39 0.41 0 0 0 0
Fetch 2100 0.09 0.11 0 8402 0 2100
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 4201 0.48 0.52 0 8402 0 2100

可以看出分区表的查询效率相当的差,原因是索引并非分区键,使用索引查询时必须

遍历所有分区,因此效率差。

删除原来的hash分区表的索引,

创建如下分区索引:

create index big_hash_idx1 on big_table_hashed(owner)
global partition by range (owner)
( partition values less than ( 'F' ),
partition values less than ( 'M' ),
partition values less than ( 'T' ),
partition values less than ( MAXVALUE )
);

再运行上述测试脚本,使用tkprof工具进行比较,结果如下:

对于hash分区表:

SELECT *
FROM
BIG_TABLE_HASHED WHERE OWNER = :B1 AND ROWNUM =1

call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 2100 0.46 1.58 0 0 0 0
Fetch 2100 0.09 0.14 0 7600 0 2100
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 4201 0.56 1.72 0 7600 0 2100

普通表:

SELECT *
FROM
BIG_TABLE WHERE OWNER = :B1 AND ROWNUM =1

call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 2100 0.46 0.38 0 0 0 0
Fetch 2100 0.06 0.11 0 8402 0 2100
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 4201 0.53 0.50 0 8402 0 2100

这一次,因为对全局索引进行了分区,hash分区表的查询效率要好的多,但即使如此,

还没有普通表的普通索引快。

测试结论:如果使用分区表,如果创建的索引不是分区键,建议使用全局索引分区,否则查询效率会很差。

参考文献:

《Oracle高效设计》
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: