時間のかかるSQLを実行する簡単な方法


はじめに

DB構築直後や検証環境でのデータがない時に遅いSQL文が必要になる時がたまにあります。たとえば、「RDSのMySQLでSlow queryの設定をしたけど本当に動いているのか確認したい」といった時です。そんな時に使える小技となります。ちなみにMySQLやOracleだけでなく他のDBでも使えますので、こちらではsqlite3を使って試しています。

データを作る

ここではtestという数値型のカラムを一つ持つテーブルをつくって、そこに10行レコードを追加しています。既にテーブルがある場合はそちらもつかえます。

sqlite> create table test (item1 int);
sqlite> select count(*) from test;
0
sqlite> insert into test values (1);
sqlite> insert into test values (2);
sqlite> insert into test values (3);
sqlite> insert into test values (4);
sqlite> insert into test values (5);
sqlite> insert into test values (6);
sqlite> insert into test values (7);
sqlite> insert into test values (8);
sqlite> insert into test values (9);
sqlite> insert into test values (10);
sqlite> select count(*) from test;
10

遅いSQL文を実行する

こんな感じのSQLを実行します。


sqlite>  select count(*) from test a , test b , test c , test d , test e;
100000

交差結合(cross join)を利用しています。テーブルが1つしかなくても別名をつけることで結合可能です。上のSQL文は各テーブルの各レコードが別のテーブルの全レコードと結合することになりますので、10の5乗の10万レコードが返されます。

でも、これでは最近のPCでは一瞬でデータが返ってきます。ということで、もう一工夫して、このSelect文の結果をtestテーブルにつっこみます。


sqlite> insert into test (item1) select a.item1 item1 from test a , test b , test c , test d , test e; 

sqlite> select count(*) from test;
100010

10万レコードのテーブルができました。で、ここに最初のSQL文を実行すると応答が返ってこないSQLが実行できます。中断するにはCtrl+cを入力してください。

まとめ

小ネタということでデータがない時に遅いSQL文を実行する方法を説明しました。sqliteはシンプルでシステムテーブル等のレコード数があまりなく、テーブルを作っていますが、MySQL、Postgres、Oracleなどではシステムテーブルに結構なレコード数があるので、テーブル作成の必要はないとおもいます。
時間のかかるSQLはCPUバウンドになります。監視ツールのチェック等にも使えます。運用環境だと悪影響を与えること間違いなしですので気をつけてください。

ではでは。