プログラムを扱っていると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