(5.6)
drop table tab1;
create table tab1(col1 int not null,col2 int,col3 char(100));
drop procedure proc1;
delimiter //
create procedure proc1()
begin
declare i int;
declare j int;
declare k int;
set i = 1;
set j = 1;
set k = 1;
while i <= 1000000 do
insert into tab1 values(i,j,rpad('A',100,j));
set i = i + 1;
set k = k + 1;
if k > 10000 then
set j = j + 1;
set k = 1;
end if;
end while;
end
//
delimiter ;
call proc1();
alter table tab1 add constraint tab1p primary key (col1);
create index ind12 on tab1(col2);
analyze table tab1;
1.インスタンスレベルでの確認
1.1.リテラルの場合
time for i in `seq 1 10000`; do
echo "prepare stmt1 from 'select * from tab1 where col1=${i}';"
echo "set @i = ${i};"
echo "execute stmt1;"
echo "deallocate prepare stmt1;"
done | mysql -u root -p'Aaa!1234' test > /dev/null
real 0m2.923s
user 0m0.586s
sys 0m0.488s
1.2.バインド変数の場合
time for i in `seq 1 10000`; do
echo "prepare stmt1 from 'select * from tab1 where col1=?';"
echo "set @i = ${i};"
echo "execute stmt1 using @i;"
echo "deallocate prepare stmt1;"
done | mysql -u root -p'Aaa!1234' test > /dev/null
real 0m2.977s
user 0m0.598s
sys 0m0.490s
→実行時間に相違なし
2.セッションレベルでの確認
2.1.リテラルの場合
drop procedure proc2;
delimiter //
create procedure proc2()
begin
declare vSQL varchar(1000);
declare i int;
declare j varchar(1000);
set i = 0;
while i <= 1000000 do
set i = i + 1;
set j = cast(i as char);
select concat('select * from tab1 where col1=',j) into vSQL;
set @q := vSQL;
set @k := i;
prepare stmt1 from @q;
execute stmt1;
deallocate prepare stmt1;
end while;
end
//
delimiter ;
time echo "call proc2()" | mysql -u root -p'Aaa!1234' test > /dev/null
real 1m2.753s
user 0m6.152s
sys 0m3.390s
2.2.バインド変数の場合
drop procedure proc2;
delimiter //
create procedure proc2()
begin
declare vSQL varchar(1000);
declare i int;
declare j varchar(1000);
set i = 0;
while i <= 1000000 do
set i = i + 1;
set j = cast(i as char);
select concat('select * from tab1 where col1=','?') into vSQL;
set @q := vSQL;
set @k := i;
prepare stmt1 from @q;
execute stmt1 using @k;
deallocate prepare stmt1;
end while;
end
//
delimiter ;
time echo "call proc2()" | mysql -u root -p'Aaa!1234' test > /dev/null
real 0m59.911s
user 0m5.990s
sys 0m3.480s
→実行時間に相違なし
(12cR1)
https://www.oracle.com/technetwork/jp/database/articles/shibacho/index-2405696-ja.html
drop table tab1 purge;
create table tab1(col1 int not null,col2 int,col3 char(100));
declare
j integer;
k integer;
begin
j := 1;
k := 1;
for i in 1..1000000 loop
insert into tab1 values(i,j,rpad('A',100,j));
commit;
k := k+1;
if k > 10000 then
j := j+1;
k := 1;
end if;
end loop;
end;
/
create unique index ind11 on tab1(col1);
alter table tab1 add constraint tab1p primary key (col1) using index ind11;
create index ind12 on tab1(col2);
exec dbms_stats.gather_table_stats(ownname => 'TEST', tabname => 'TAB1');
1.インスタンスレベルでの確認
1.1.リテラルの場合
time for i in `seq 1 10000`; do
echo "variable i int"
echo "execute :i := ${i}"
echo "select * from tab1 where col1=${i};"
done | sqlplus test/test > /dev/null
real 0m11.432s
user 0m3.411s
sys 0m0.401s
1.2.バインド変数の場合
time for i in `seq 1 10000`; do
echo "variable i int"
echo "execute :i := ${i}"
echo "select * from tab1 where col1=:i;"
done | sqlplus test/test > /dev/null
real 0m1.143s
user 0m1.055s
sys 0m0.203s
→バインド変数化により処理時間が短くなる
2.セッションレベルでの確認
2.1.リテラルの場合
set timin on
declare
r_tab1 tab1%rowtype;
vSQL varchar2(1000);
j varchar2(1000);
begin
for i in 1..10000 loop
j := to_char(i);
vSQL := 'select * from tab1 where col1= ' || j;
execute immediate vSQL into r_tab1;
end loop;
end;
/
経過: 00:00:06.87
2.2.バインド変数の場合
set timin on
declare
r_tab1 tab1%rowtype;
vSQL varchar2(1000);
j varchar2(1000);
begin
for i in 1..10000 loop
j := to_char(i);
vSQL := 'select * from tab1 where col1= ' || ':k';
execute immediate vSQL into r_tab1 using i;
end loop;
end;
/
経過: 00:00:00.18
→バインド変数化により処理時間が短くなる
(9.4)
drop table tab1;
create table tab1(col1 int not null,col2 int,col3 char(100));
do $$
declare
j integer;
k integer;
begin
j := 1;
k := 1;
for i in 1..1000000 loop
insert into tab1 values(i,j,rpad('A',100,j::char(3)));
k := k+1;
if k > 10000 then
j := j+1;
k := 1;
end if;
end loop;
end
$$
;
create unique index ind11 on tab1(col1);
alter table tab1 add constraint tab1p primary key using index ind11;
create index ind12 on tab1(col2);
analyze tab1;
1.インスタンスレベルでの確認
1.1.リテラルの場合
time for i in `seq 1 10000`; do
echo "prepare stmt1(int) as select * from tab1 where col1=${i};"
echo "execute stmt1(${i});"
echo "deallocate stmt1;"
done | psql test > /dev/null
real 0m3.206s
user 0m0.736s
sys 0m0.317s
1.2.バインド変数の場合
time for i in `seq 1 10000`; do
echo "prepare stmt1(int) as select * from tab1 where col1=\$1;"
echo "execute stmt1(${i});"
echo "deallocate stmt1;"
done | psql test > /dev/null
real 0m3.233s
user 0m0.706s
sys 0m0.294s
→実行時間に相違なし
2.セッションレベルでの確認
2.1.リテラルの場合
\timing on
do $$
declare
j varchar(100);
begin
for i in 1..1000000 loop
j := i::varchar;
execute 'prepare stmt1(int) as select * from tab1 where col1=' || j;
execute 'execute stmt1(' || quote_literal(i) || ')';
execute 'deallocate stmt1';
end loop;
end
$$
;
時間: 94182.694 ms
2.2.バインド変数の場合
\timing on
do $$
declare
j varchar(100);
begin
for i in 1..1000000 loop
j := i::varchar;
execute 'prepare stmt1(int) as select * from tab1 where col1=' || '$1';
execute 'execute stmt1(' || quote_literal(i) || ')';
execute 'deallocate stmt1';
end loop;
end
$$
;
時間: 92303.446 ms
→実行時間に相違なし
(2014)
drop table tab1;
create table tab1(col1 int not null,col2 int,col3 char(100));
declare @i int;
declare @j int;
declare @k int;
set @i= 1;
set @j= 1;
set @k= 1;
while (@i <= 1000000)
begin
insert into tab1 values (@i,@j,'A' + left(replicate(convert(varchar,@j),100),99));
set @i = @i + 1;
set @k = @k + 1;
if @k > 10000
begin
set @j = @j + 1;
set @k = 1;
end
end
go
alter table tab1 add constraint tab1p primary key (col1);
create index ind12 on tab1(col2);
update statistics tab1;
1.インスタンスレベルでの確認
1.1.リテラルの場合
drop procedure dbo.proc1;
go
create procedure dbo.proc1(@param1 int)
as
begin
declare @i int;
declare @j nvarchar(100);
declare @vSQL nvarchar(100);
declare @vSQLParm nvarchar(100);
set @i= @param1;
set @j = convert(nvarchar,@i);
set @vSQL = 'select * from tab1 where col1 = ' + @j;
set @vSQLParm = '@col1 int';
execute sp_executesql @vSQL, @vSQLParm, @col1 = @i
end
go
@echo off
echo %TIME%
for /l %%n in (1,1,10000) do (
sqlcmd -d test -b -Q "exec dbo.proc1 %%n" > nul
)
echo %TIME%
exit /b 0
→6分16秒
1.2.バインド変数の場合
drop procedure dbo.proc1;
go
create procedure dbo.proc1(@param1 int)
as
begin
declare @i int;
declare @j nvarchar(100);
declare @vSQL nvarchar(100);
declare @vSQLParm nvarchar(100);
set @i= @param1;
set @j = convert(nvarchar,@i);
set @vSQL = 'select * from tab1 where col1 = ' + '@col1';
set @vSQLParm = '@col1 int';
execute sp_executesql @vSQL, @vSQLParm, @col1 = @i
end
go
@echo off
echo %TIME%
for /l %%n in (1,1,10000) do (
sqlcmd -d test -b -Q "exec dbo.proc1 %%n" > nul
)
echo %TIME%
exit /b 0
→6分54秒
→実行時間に相違なし
2.セッションレベルでの確認
2.1.リテラルの場合
drop procedure dbo.proc1;
go
create procedure dbo.proc1
as
begin
declare @i int;
declare @j nvarchar(100);
declare @vSQL nvarchar(100);
declare @vSQLParm nvarchar(100);
set @i= 1;
while (@i <= 100000)
begin
set @j = convert(nvarchar,@i);
set @vSQL = 'select * from tab1 where col1 = ' + @j;
set @vSQLParm = '@col1 int';
execute sp_executesql @vSQL, @vSQLParm, @col1 = @i
set @i = @i + 1;
end
end
go
echo %TIME%
sqlcmd -d test -b -Q "exec dbo.proc1" > nul
echo %TIME%
→39秒
2.2.バインド変数の場合
drop procedure dbo.proc1;
go
create procedure dbo.proc1
as
begin
declare @i int;
declare @j nvarchar(100);
declare @vSQL nvarchar(100);
declare @vSQLParm nvarchar(100);
set @i= 1;
while (@i <= 100000)
begin
set @j = convert(nvarchar,@i);
set @vSQL = 'select * from tab1 where col1 = ' + '@col1';
set @vSQLParm = '@col1 int';
execute sp_executesql @vSQL, @vSQLParm, @col1 = @i
set @i = @i + 1;
end
end
go
echo %TIME%
sqlcmd -d test -b -Q "exec dbo.proc1" > nul
echo %TIME%
→2秒
→バインド変数化により処理時間が短くなる