10. 大量データのインサート方法
• 検証(インデックスを先に作成)
• 次にインデックスを作成します。
• 8つのインデックスを作成します。
10
create index c1_index on itest (c1);
create index c2_index on itest (c2);
create index c3_index on itest (c3);
create index c4_index on itest (c4);
create index c5_index on itest (c5);
create index c6_index on itest (c6);
create index c7_index on itest (c7);
create index c8_index on itest (c8);
11. 大量データのインサート方法
• 検証(インデックスを先に作成)
• 10万件のデータをインサートするのにかかる時間を検証します。
11
select now(); -- 開始時刻を表示
-- 再帰SQLを使用して、10万件のデータを作成する
insert into itest
with recursive DUMMY(i) as
(
select 1 i
union all
select i+1 from DUMMY where i < 100000
)
select i , 'c1' || i , 'c2' || i, 'c3' || i, 'c4' || i, 'c5' ||
i, 'c6' || i, 'c7' || i, 'c8' || i from DUMMY;
select now(); -- 終了時刻を表示
14. 大量データのインサート方法
• 検証(インデックスを後に作成)
• 次は、データを作成した後にインデックスを作成する場合を検証しま
す。
• テーブルを一度削除して再作成し、空の状態にしてください。
14
select now(); -- 開始時刻を表示
-- 10万件インサート
insert into itest
with recursive DUMMY(i) as
(select 1 i
union all
select i+1 from DUMMY where i < 100000
)
select i , 'c1' || i , 'c2' ||
i, 'c3' || i, 'c4' || i, 'c5' ||
i, 'c6' || i, 'c7' || i, 'c8' ||
i from DUMMY;
-- インデックス作成
create index c1_index on itest (c1);
create index c2_index on itest (c2);
create index c3_index on itest (c3);
create index c4_index on itest (c4);
create index c5_index on itest (c5);
create index c6_index on itest (c6);
create index c7_index on itest (c7);
create index c8_index on itest (c8);
select now(); -- 終了時刻を表示
23. バルクインサート
• サンプル(バルクインサート)
• 以下はバルクインサートのプログラムをバルクインサートを使用する
ものに修正したものです。
23
create or replace procedure insert_test_bulk is
cursor csrItest is select * from itest; -- カーソルの定義
type tItest is table of itest%rowtype index by binary_integer;
wk_itest tItest; -- レコード型の配列
begin
open csrItest;
loop
fetch csrItest bulk collect into wk_itest limit 1000;
exit when wk_itest.count = 0;
forall i in 1..wk_itest.count
insert into itest2 values wk_itest(i); -- 1000件をまとめてインサート
commit;
end loop;
close csrItest;
end;
24. バルクインサート
• 比較
• 通常のインサートでは、ループしながら1件ずつインサートしていま
す。
• 一方でバルクインサートの方は、1000件ずつまとめてインサートをし
ているのが分かります。
• 1000の数値を変更することで、1回のインサートのレコード数を変更
することができます。
24
fetch csrItest bulk collect into wk_itest limit 1000;
exit when wk_itest.count = 0;
forall i in 1..wk_itest.count
insert into itest2 values wk_itest(i);
fetch csrItest into wk_itest;
exit when csrItest%notfound;
insert into itest2 values wk_itest;
通常のインサート バルクインサート
28. テストデータの作成(再帰SQL)
上記のSQLを実行すると、図のように
10000件のレコードを取得できる。
大量のテストデータをインサートする際などに役立つ。
28
実行結果
-- 例 PostgreSQLの場合
with recursive DUMMY(i) as
(select 1 i
union all
select i+1 from DUMMY where i < 10000)
select i as id, 'テスト' as name from DUMMY;
id name
1 テスト
2 テスト
3 テスト
4 テスト
… …
9997 テスト
9998 テスト
9999 テスト
10000 テスト
-- 例 Oracleの場合
with DUMMY(i) as
(select 1 I from dual
union all
select i+1 from DUMMY where i < 10000)
select i as id, 'テスト' as name from DUMMY;
29. テストデータの作成
• クロス結合の使用
• クロス結合はプログラム内で使用することはほぼないが、
大量のテストデータを作成するときには便利です。
• pg_dependはシステムカタログにあるテーブル
7000件以上のレコードがある。cross joinすることで、
7000 × 7000 で 49,000,000以上のレコードが取得される。
29
実行結果
-- 例 PostgreSQL
select row_number() over(order by 1) num, 'test'
from (select *
from pg_depend A -- 約7000件
cross join
pg_depend B -- 約7000件
) A;
num test
1 test
2 test
3 test
4 test
5 test
6 test
7 test
8 test
・・・ ・・・
33. ストアドプロシージャの活用
• インサート処理をするストアド
• 以下は、データのインサートの際に使用したプログラムです。
• ループ処理しながらレコードをインサートしています。
33
create or replace function insert_itest(start_id int, end_id int) returns decimal as '
begin
for i in start_id..end_id loop
insert into itest values(i , ''c1'' || i , ''c2'' || i, ''c3'' || i
, ''c4'' || i, ''c5'' || i, ''c6'' || i
, ''c7'' || i, ''c8'' || i);
end loop;
return 0;
end;
' language plpgsql;
60. Oracleのストアド
• Oracle版の合計算出用ストアド
60
create or replace function sales_sum return number is
-- 商品テーブル用のカーソル
cursor csrProducts is select * from products where category_id = 3;
-- 商品カーソル格納用
wk_product csrProducts%ROWTYPE;
-- 販売テーブル用のカーソル
cursor csrSales is select * from sales where products_id = wk_product.products_id;
-- 販売カーソル格納法
wk_sales csrSales%ROWTYPE;
sales_sum number; -- 合計算出用
begin
sales_sum := 0;
open csrProducts; -- 商品カーソルでループ
loop
-- ⇓続く
61. Oracleのストアド
• Oracle版の合計算出用ストアド(続き)
61
fetch csrProducts into wk_product;
exit when csrProducts%NOTFOUND;
open csrSales; -- 販売カーソルでループ
loop
fetch csrSales into wk_sales;
exit when csrSales%NOTFOUND;
-- 合計加算
sales_sum := sales_sum + (wk_product.p_price * wk_sales.unit_sales);
end loop;
close csrSales;
end loop;
close csrProducts;
return sales_sum;
end;
/