普通表索引,分区表局部索引和分区表的全局索引分区的效率对比测试
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高效设计》
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高效设计》
相关文章推荐
- 测试分区维护对于字段索引的影响(包括本地/全局索引分区与普通分区)
- PLSQL,Oracle 测试 ,创建局部分区索引,全局未分区索引 ,全局分区索引,以及失效重建
- 分区表、分区索引和全局索引部分总结
- oracle的分区表、分区索引和全局索引部分总结
- 组合分区与范围分区效率对比测试(1)
- 分区表、分区索引和全局索引部分总结
- 组合分区与范围分区效率对比测试(2)
- 全局分区索引与局部分区索引
- 分区表、分区索引和全局索引部分总结
- 分区表、分区索引和全局索引部分总结
- mysql中普通索引和唯一索引的效率对比
- 组合分区与范围分区效率对比测试(3)
- 分区表、分区索引和全局索引部分总结
- PLSQL_Oracle分区表和相应的分区索引管理和使用(案例)(创建交易表等大表时进行分区提高效率)
- 分区表、分区索引和全局索引部分总结
- 测试分区表,以及在现有表上新建分区方案,以及把分区表变为普通表测试代码!!
- Oracle之分区表与全局索引和局部索引
- 【Oracle】关于局部索引和全局索引的测试
- 索引分区分为:本地(局部)索引(local index) 全局索引(global index)
- 分区表 主键全局索引和分区索引区别