テーブル変更と更新

(12R1)

 


--データ準備
set time on
set timing on

drop table tab1 purge;
create table tab1(col1 int,col2 timestamp);
alter table tab1 add constraint tab1p primary key (col1);


declare
begin
for i in 1..100000 loop
insert into tab1 values(i,NULL);
commit;
end loop;
end;
/

--session1から実行(カラム追加・削除)

declare
sSQL varchar2(1000);
begin
while true loop
sSQL :='alter table tab1 add (col3 int)';
execute immediate sSQL;

sSQL :='alter table tab1 drop (col3)';
execute immediate sSQL;
end loop;
end;
/

 

--session2から実行(更新)

declare
begin
for i in 1..100000 loop
update tab1 set col2 = systimestamp where col1 = i;
commit;

end loop;
end;
/

 

--結果

開始後しばらくして、カラム追加・削除側で「ORA-00054: リソース・ビジー」発生
※下記SQLをカラム追加・削除側で実行することでリソースビジーは回避可能
alter session set ddl_lock_timeout = 60;


カラム追加・削除有の場合
→経過: 00:00:49.98

カラム追加・削除なしの場合
→経過: 00:00:10.99

 

(5.6)

--データ準備

drop table tab1;
create table tab1(col1 int,col2 timestamp(3));
alter table tab1 add constraint tab1p primary key(col1);


drop procedure proc1;

delimiter //
create procedure proc1()
begin
declare i int;

set i = 1;

while i <= 100000 do
insert into tab1 values(i,null);
set i = i + 1;
end while;
end
//
delimiter ;

call proc1();

--session1から実行(カラム追加・削除)

drop procedure proc2;

delimiter //
create procedure proc2()
begin
declare vSQL varchar(1000);


while true do
set @q := 'alter table tab1 add (col3 int)';
prepare stmt from @q;
execute stmt;
deallocate prepare stmt;

set @q := 'alter table tab1 drop col3';
prepare stmt from @q;
execute stmt;
deallocate prepare stmt;

end while;
end
//
delimiter ;

call proc2();

--session2から実行(更新)

drop procedure proc3;

delimiter //
create procedure proc3()
begin
declare i int;

set i = 1;

while i <= 100000 do
update tab1 set col2 = CURRENT_TIMESTAMP(3) where col1 = i;
set i = i + 1;
end while;
end
//
delimiter ;

call proc3();

--結果

エラー発生なし


カラム追加・削除有の場合
→2 min 56.68 sec

カラム追加・削除なしの場合
→32.83 sec

 

 

(9.4)
--データ準備
\timing

drop table tab1;
create table tab1(col1 int,col2 timestamp);
create unique index ind1 on tab1(col1);
alter table tab1 add constraint tab1p primary key using index ind1;

insert into tab1 select generate_series(1,1000),NULL;


--session1から実行(カラム追加・削除)


drop function fun1();

create or replace function fun1()
returns void as
$$
DECLARE

BEGIN
execute 'alter table tab1 add col3 int';
EXCEPTION
WHEN others THEN
RAISE NOTICE 'SQLERRM= %,SQLSTATE=%',SQLERRM,SQLSTATE;
END
$$ language 'plpgsql';

drop function fun2();

create or replace function fun2()
returns void as
$$
DECLARE

BEGIN
execute 'alter table tab1 drop col3';
EXCEPTION
WHEN others THEN
RAISE NOTICE 'SQLERRM= %,SQLSTATE=%',SQLERRM,SQLSTATE;

END
$$ language 'plpgsql';

--
for i in `seq 1000`
do
SQL="psql -c 'select fun1()' test"
eval ${SQL}
SQL="psql -c 'select fun2()' test"
eval ${SQL}
done
--


--session2から実行(更新)

drop function fun3();

create or replace function fun3(int)
returns void as
$$
DECLARE
vSQL varchar(1000);

num int;
BEGIN
num := $1;
vSQL := 'update tab1 set col2 = clock_timestamp() where col1 = ' || cast(num as varchar);
execute vSQL;
EXCEPTION
WHEN others THEN
RAISE NOTICE 'SQLERRM= %,SQLSTATE=%',SQLERRM,SQLSTATE;
END
$$ language 'plpgsql';

--
time for i in `seq 1000`
do
SQL="psql -c 'select fun3("${i}")' test"
eval ${SQL}
done
--


--結果

ループ回数10000の場合、
ERROR: tables can have at most 1600 columns

カラムを削除してもトータルで1600回カラム定義を行うとエラーとなる模様。
バキュームしても改善せず。
→ループ回数を1000に変更して実施


カラム追加・削除有の場合

real 0m32.405s
user 0m2.717s
sys 0m4.498s


カラム追加・削除なしの場合

real 0m16.554s
user 0m2.642s
sys 0m4.532s

 

(2014)

SET STATISTICS TIME ON

--データ準備
drop table tab1;
create table tab1(col1 int not null,col2 datetime2);
alter table tab1 add constraint tab1p primary key(col1);


DECLARE @i integer;
SET @i = 1;
WHILE @i <= 100000
BEGIN
insert into tab1 values(@i,NULL);
SET @i = @i + 1;
END

--session1から実行(カラム追加・削除)


DROP PROCEDURE dbo.proc1;
GO
CREATE PROCEDURE dbo.proc1
AS
BEGIN
DECLARE @vSQL varchar(1000);
set @vSQL = 'alter table tab1 add col3 int';
execute(@vSQL);
END
GO

DROP PROCEDURE dbo.proc2;
GO
CREATE PROCEDURE dbo.proc2
AS
BEGIN
DECLARE @vSQL varchar(1000);
set @vSQL = 'alter table tab1 drop column col3';
execute(@vSQL);
END
GO

--

@echo off

:LOOP
sqlcmd -d test -b -Q "set nocount on; exec test.dbo.proc1"
sqlcmd -d test -b -Q "set nocount on; exec test.dbo.proc2"
goto :LOOP

exit /b 0

 


--

--session2から実行(更新)

DROP PROCEDURE dbo.proc3;
GO
CREATE PROCEDURE dbo.proc3
AS
BEGIN
DECLARE @i integer;
SET @i = 1;
WHILE @i <= 100000
BEGIN
update tab1 set col2 = GETDATE() where col1 = @i;
SET @i = @i + 1;
END
END
GO

EXEC test.dbo.proc3;
GO


--結果

エラー発生なし


カラム追加・削除有の場合
→CPU 時間 = 12625 ミリ秒、経過時間 = 54685 ミリ秒

カラム追加・削除なしの場合
→CPU 時間 = 9953 ミリ秒、経過時間 = 32534 ミリ秒