データに依存するが、
Oracleではdeterministic指定の効果を確認できた。
MySQLとPostgreSQLでは効果を確認できなかった。
(8.0.27)
-- 1. テストデータ作成
drop table tab1;
create table tab1(
col1 int primary key
,col2 varchar(100)
,col3 varchar(100)
);
drop procedure proc1;
delimiter //
create procedure proc1(in x int)
begin
declare i int;
set i = 0;
start transaction;
while i < x do
set i = i + 1;
insert into tab1 values(
i
,substring(md5(rand()), 1, 30)
,'123456789012345678901234567890'
);
end while;
commit;
end
//
delimiter ;
call proc1(10000000);
select count(*) from tab1;
select * from tab1 order by rand() limit 20;
-- 2. ファンクション作成
drop function fun1;
delimiter //
create function fun1(p1 varchar(100) )
returns varchar(100)
no sql
begin
return concat('XXXXX' , substr(p1,6) );
end//
delimiter ;
drop function fun2;
delimiter //
create function fun2(p1 varchar(100) )
returns varchar(100)
deterministic
no sql
begin
return concat('XXXXX' , substr(p1,6) );
end//
delimiter ;
select fun1('123456789012345678901234567890');
select fun2('123456789012345678901234567890');
-- 3. 時間計測
select ps_current_thread_id();
select * from sys.memory_by_thread_by_current_bytes
where thread_id = 46\G
-- 3.1 ランダムデータでdeterministicなし
drop table tab2;
create table tab2 as select col1,fun1(col2) col2 from tab1;
(2 min 34.02 sec)
current_allocated: 1011.25 KiB
--- 3.2 一様データでdeterministicなし
drop table tab2;
create table tab2 as select col1,fun1(col3) col2 from tab1;
(3 min 10.72 sec)
current_allocated: 999.77 KiB
-- 3.3 ランダムデータでdeterministicあり
drop table tab2;
create table tab2 as select col1,fun2(col2) col2 from tab1;
(2 min 26.91 sec)
current_allocated: 1.00 MiB
--- 3.4 一様データでdeterministicあり
drop table tab2;
create table tab2 as select col1,fun2(col3) col2 from tab1;
(2 min 35.31 sec)
current_allocated: 1013.18 KiB
-- 4. 結果
ランダムデータでdeterministicの効果なし。
一様データでもdeterministicの効果は確認できなかった。
(19c)
https://www.ashisuto.co.jp/db_blog/article/20170322_session_memory.html
http://stevenfeuersteinonplsql.blogspot.com/2020/08/the-differences-between-deterministic.html
-- 1. テストデータ作成
drop table tab1 purge;
create table tab1(
col1 int primary key
,col2 varchar2(100)
,col3 varchar2(100)
);
declare
begin
for i in 1..10000000 loop
insert into tab1 values
(i
,substr(standard_hash(dbms_random.value(), 'MD5'),1,30)
,'123456789012345678901234567890'
);
end loop;
end;
/
commit;
select count(*) from tab1;
select * from tab1 order by dbms_random.value() fetch first 20 rows only;
-- 2. ファンクション作成
create or replace function fun1 (p1 in varchar2) return varchar2
is
begin
return 'XXXXX' || substr(p1,6);
end;
/
create or replace function fun2 (p1 in varchar2) return varchar2
deterministic
is
begin
return 'XXXXX' || substr(p1,6);
end;
/
select fun1('123456789012345678901234567890') from dual;
select fun2('123456789012345678901234567890') from dual;
-- 3. 時間計測
set timing on
select
s.sid
,s.serial#
,s.state
,s.status
,p.pga_alloc_mem/1024/1024
from v$session s,v$process p
where s.paddr = p.addr
and s.sid = 59;
-- 3.1 ランダムデータでdeterministicなし
drop table tab2 purge;
create table tab2 as select col1,fun1(col2) col2 from tab1;
経過: 00:00:32.56
実行時PGAサイズ = 27MB
--- 3.2 一様データでdeterministicなし
drop table tab2 purge;
create table tab2 as select col1,fun1(col3) col2 from tab1;
経過: 00:00:32.01
実行時PGAサイズ = 30MB
-- 3.3 ランダムデータでdeterministicあり
drop table tab2 purge;
create table tab2 as select col1,fun2(col2) col2 from tab1;
経過: 00:00:32.01
実行時PGAサイズ = 30MB
--- 3.4 一様データでdeterministicあり
drop table tab2 purge;
create table tab2 as select col1,fun2(col3) col2 from tab1;
経過: 00:00:09.06 ★
実行時PGAサイズ = 30MB
-- 4. 結果
ランダムデータでdeterministicの効果なし。
一様データでdeterministicの効果あり。 ★
deterministicを指定しても特にPGAサイズが大きくなる傾向は見られなかった
(14)
-- 1. テストデータ作成
drop table tab1;
create table tab1(
col1 int primary key
,col2 varchar(100)
,col3 varchar(100)
);
start transaction;
insert into tab1 select
g
,substring(md5(random()::text), 1, 30)
,'123456789012345678901234567890'
from generate_series(1,10000000) g;
commit;
select count(*) from tab1;
select * from tab1 order by random() limit 20;
-- 2. ファンクション作成
create or replace function fun1(in p1 varchar)
returns varchar as $$
begin
return 'XXXXX' || substr(p1,6);
end;
$$ language plpgsql;
create or replace function fun2(in p1 varchar)
returns varchar as $$
begin
return 'XXXXX' || substr(p1,6);
end;
$$ language plpgsql immutable;
select fun1('123456789012345678901234567890');
select fun2('123456789012345678901234567890');
-- 3. 時間計測
\timing 1
set log_statement_stats = 'on';
show log_statement_stats;
-- 3.1 ランダムデータでimmutableなし
drop table tab2;
create table tab2 as select col1,fun1(col2) col2 from tab1;
時間: 26654.378 ミリ秒(00:26.654)
171932 kB max resident size
--- 3.2 一様データでimmutableなし
drop table tab2;
create table tab2 as select col1,fun1(col3) col2 from tab1;
時間: 23447.982 ミリ秒(00:23.448)
171932 kB max resident size
-- 3.3 ランダムデータでimmutableあり
drop table tab2;
create table tab2 as select col1,fun2(col2) col2 from tab1;
時間: 22697.288 ミリ秒(00:22.697)
171932 kB max resident size
--- 3.4 一様データでimmutableあり
drop table tab2;
create table tab2 as select col1,fun2(col3) col2 from tab1;
時間: 25635.885 ミリ秒(00:25.636)
171932 kB max resident size
-- 4. 結果
ランダムデータでimmutableの効果なし。
一様データでもimmutableの効果は確認できなかった。
(2019)
IsDeterministicプロパティはSQL Server によって自動的に決定されるため、検証不可。