(5.6)
テーブルの件数:100万
取得件数:1万,10万,100万
フルスキャンとインデックスアクセスの処理時間を比較
drop table tab1;
drop table tab2;
create table tab1(col1 int);
create table tab2(col1 int);
alter table tab2 add constraint tab2pk primary key(col1);
drop procedure proc1;
delimiter //
create procedure proc1(in param1 integer)
begin
declare i int;
set @q := 'truncate table tab1';
prepare stmt from @q;
execute stmt;
deallocate prepare stmt;
set i = 1;
while i <= param1 do
insert into tab1 values(i);
set i = i + 1;
end while;
end
//
delimiter ;
call proc1(1000000);
select count(*) from tab1;
insert into tab2 select * from tab1 order by rand();
select * from tab2 limit 100;
→MySQLの主キーはクラスタ化インデックスのため、物理的にランダム格納はできない
analyze table tab2;
deallocate prepare plan;
prepare plan from '
explain
select
count(*)
from tab2 t1 use index (primary)
where col1 <= ?
';
deallocate prepare plan;
prepare plan from '
explain
select
count(*)
from tab2 t1 ignore index (primary)
where col1 <= ?
';
deallocate prepare plan;
prepare plan from '
select
count(*)
from tab2 t1 ignore index (primary)
where col1 <= ?
';
deallocate prepare plan;
prepare plan from '
select
count(*)
from tab2 t1 use index (primary)
where col1 <= ?
';
set @a = 10000;
set @a = 100000;
set @a = 1000000;
execute plan using @a;
--確認結果
フルスキャンの場合
1万件→0.18 sec
10万件→0.18 sec
100万件→0.20 sec
インデックスアクセスの場合
1万件→0.00 sec
10万件→0.02 sec
100万件→0.23 sec
(12cR1)
テーブルの件数:100万
取得件数:1万,10万,100万
フルスキャンとインデックスアクセスの処理時間を比較
drop table tab1 purge;
drop table tab2 purge;
create table tab1(col1 int);
create table tab2(col1 int);
create index ind2 on tab2(col1);
alter table tab2 add constraint tab2pk primary key (col1) using index ind2;
create or replace procedure proc1(param1 in number) as
begin
execute immediate 'truncate table tab1';
for i in 1..param1 loop
insert into tab1 values(i);
commit;
end loop;
end;
/
exec proc1(1000000);
select count(*) from tab1;
insert into tab2 select * from tab1 order by dbms_random.value();
commit;
select * from tab2 fetch first 100 rows only;
exec dbms_stats.gather_table_stats('TEST','TAB2');
set time on
set timing on
variable val1 number;
execute :val1 := 10000
execute :val1 := 100000
execute :val1 := 1000000
explain plan for
select /*+ FULL(T1) */
count(*)
from tab2 T1
where col1 <= :val1
;
SELECT PLAN_TABLE_OUTPUT FROM TABLE(DBMS_XPLAN.DISPLAY());
explain plan for
select /*+ INDEX(T1 IND1) */
count(*)
from tab2 T1
where col1 <= :val1
;
SELECT PLAN_TABLE_OUTPUT FROM TABLE(DBMS_XPLAN.DISPLAY());
--確認結果
フルスキャンの場合
1万件→経過: 00:00:00.01
10万件→経過: 00:00:00.01
100万件→経過: 00:00:00.02
インデックスアクセスの場合
1万件→経過: 00:00:00.00
10万件→経過: 00:00:00.01
100万件→経過: 00:00:00.05
(9.4)
テーブルの件数:100万
取得件数:1万,10万,100万
フルスキャンとインデックスアクセスの処理時間を比較
drop table tab1;
drop table tab2;
create table tab1(col1 int);
create table tab2(col1 int);
create unique index ind2 on tab2(col1);
alter table tab2 add constraint tab2pk primary key using index ind2;
create or replace function fun1(integer)
returns void as
$$
begin
execute 'truncate table tab1';
for i in 1..$1 loop
insert into tab1 values(i);
end loop;
end;
$$ language plpgsql;
select fun1(1000000);
select count(*) from tab1;
insert into tab2 select * from tab1 order by random();
select * from tab2 limit 100;
analyze tab2;
\timing 1
deallocate plan;
prepare plan (int) as
select /*+ SeqScan(t1) */
count(*)
from tab2 t1
where col1 <= $1
;
deallocate plan;
prepare plan (int) as
select /*+ IndexScan(t1 tab2pk) */
count(*)
from tab2 t1
where col1 <= $1
;
explain analyze execute plan(10000);
explain analyze execute plan(100000);
explain analyze execute plan(1000000);
--確認結果
フルスキャンの場合
1万件→67.663 ms
10万件→76.950 ms
100万件→153.814 ms
インデックスアクセスの場合
1万件→7.422 ms
10万件→73.810 ms
100万件→688.718 ms
(2014)
テーブルの件数:100万
取得件数:1万,10万,100万
フルスキャンとインデックスアクセスの処理時間を比較
drop table tab1;
drop table tab2;
create table tab1(col1 int not null);
create table tab2(col1 int not null);
alter table tab2 add constraint tab2pk primary key nonclustered (col1);
drop procedure proc1;
create procedure proc1(@param1 int)
as
begin
declare @i integer;
execute('truncate table tab1');
set @i = 1;
while @i <= @param1
begin
insert into tab1 values(@i);
set @i = @i + 1;
end
end
;
exec proc1 1000000;
select count(*) from tab1;
insert into tab2 select * from tab1 order by newid() ;
select top 100 * from tab2;
→非クラスタ化インデックスにしてもランダムソートされない
update statistics tab2;
set statistics time on
set showplan_text on
declare @a int;
set @a = 10000;
select
count(*)
from tab2 t1 with(forcescan)
where col1 <= @a
;
declare @a int;
set @a = 100000;
select
count(*)
from tab2 t1 with(forcescan)
where col1 <= @a
;
declare @a int;
set @a = 1000000;
select
count(*)
from tab2 t1 with(forcescan)
where col1 <= @a
;
declare @a int;
set @a = 10000;
select
count(*)
from tab2 t1 with(index(tab2pk))
where col1 <= @a
;
declare @a int;
set @a = 100000;
select
count(*)
from tab2 t1 with(index(tab2pk))
where col1 <= @a
;
declare @a int;
set @a = 1000000;
select
count(*)
from tab2 t1 with(index(tab2pk))
where col1 <= @a
;
--確認結果
フルスキャンの場合
1万件→45 ミリ秒
10万件→42 ミリ秒
100万件→62 ミリ秒
インデックスアクセスの場合
1万件→0 ミリ秒
10万件→7 ミリ秒
100万件→68 ミリ秒