浜松のWEBシステム開発・スマートフォンアプリ開発・RTK-GNSS関連の開発はお任せください
株式会社シーポイントラボ
TEL:053-543-9889
営業時間:9:00~18:00(月〜金)
住所:静岡県浜松市中区富塚町1933-1 佐鳴湖パークタウンサウス2F

高速化のために一度の小さな問い合わせで済むSQL文を作る

 プログラムを扱っているとDB(データベース)に接続する必要のある場面がいくつもあります。DBへのアクセスにかかる時間、実行にかかる時間は無視出来ず、実行速度のボトルネックになることがあります。DBの内部をチューニングする事でも速度の向上はできますが、問い合わせの回数、DBから引っ張ってくるデータの大きさといった部分を問い合わせ文の工夫によって少なく、小さくすることによっても高速化はできます。
 よくある場面は、必要なデータが複数のテーブルに分散している、あるテーブル中に格納されたデータを基にした条件に合致するデータのみを取得したい、といったものです。こういった時、それぞれのテーブルをそのまま扱うようなことをすると次の様なコードが生まれます。

$arr = query('SELECT * FROM master_table');
foreach($arr as $v){
	$hoge_addr = query("SELECT * FROM hoge_table WHERE addr = '${arr['addr']}'");
	...
	...
}

 こういった何度も問い合わせをDBに送る様なコードは実行にかかる時間が長くなりがちです。DBへの問い合わせは少ない回数で少ないデータをとれるようにした方がプログラムは高速になります。必要最小限のデータの取得は*を使わずに細かく指定することでできます。問い合わせを少ない回数で行うためにはAS、JOIN、入れ子内部のSELECTが便利です。

SELECT * FROM(
	SELECT
		master_table.id,
		master_table.name,
		hoge_addr.name AS name1,
		hoge_addr2.name AS name2,
		fuga_table.name
	FROM
		master_table
		INNER JOIN
			hoge_table AS hoge_addr
		ON  master_table.addr = hoge_addr.addr
		INNER JOIN
			hoge_table AS hoge_addr2
		ON  master_table.addr2 = hoge_addr.addr
		INNER JOIN
			fuga_table
		ON  master_table.branch = fuga_table.id
) AS tmptable
WHERE
	name1 = 'hogehoge'

 SELECTの結果はそのままテーブルとして扱うことが出来ます。ここではそうまとめの様に扱っていますがWHERE句中に使うこともできます。

WHERE id IN (SELECT hoge_id FROM hoge_table WHERE hogehoge = 'fugafuga')

とすればINにより()内の結果であるhoge_idのいずれかと一致するIDという条件を作れます。
 JOINは表の結合です。オプションは様々でINNER以外も多く使われます。ASはそのままA as BでAをBとして扱うという句です。JOINとASを組み合わせることで同じ表から違う条件で汲み上げた結果を一つの表にまとめられます。

master_table
INNER JOIN
	hoge_table AS hoge_addr
ON  master_table.addr = hoge_addr.addr
INNER JOIN
	hoge_table AS hoge_addr2
ON  master_table.addr2 = hoge_addr.addr
  • この記事いいね! (0)