SQLのJOINについて考える
「JOINは使わない方が良い」というのを小耳に挟んで「なぜだろう」と思っていたのですが、ひとつの理由が分かったのでそれを記しておきます。
SQLのJOINについて考えるべく、Twitterみたいな掲示板システムを考えてみます。
自分がフォローしているユーザーのコメントをすべて取得するような状況です。
friendテーブル
まず、友達の一覧を保持するテーブルfriendが必要です。
自分のIDと友達のIDを保持しておきます。
CREATE TABLE friend (id int, friend_id int);
commentテーブル
次に投稿を保持するテーブルcommentが必要です。
発言者のIDと、コメントの本文が必要です。
CREATE TABLE comment(id int, comment text);
JOINを使って友人のコメントを取得する
非常に基本的なSQLで書くことができます。
たとえば、自分のIDが1なら、次のようなSQL文になります。
SELECT * FROM comment AS c JOIN friend AS f ON c.id = f.friend_id WHERE f.id = 1;
JOINを使わないで友人のコメントを取得する
友人のIDの一覧を取得する
JOINを使わないので、SQLを分割する必要があります。
まずは、自分のIDを元に友人のID一覧を取得します。
SELECT friend_id FROM friend WHERE id = 1;
友人のIDを元にコメントの一覧を取得する
つづいて、取得したidをPHPなどで整形して、コメント取得のSQLに投げ込みます。
たとえば、友人が4人いて、友人のIDが2,3,4,5と取得できた場合は次のようなSQLになります。
SELECT * FROM comment WHERE id IN (2,3,4,5);
どちらのSQLが優れているか?
この比較は難しいかもしれませんが、ひとつの判断の観点として、システムの規模があげられると思います。
JOINを使った方が楽
この説明を見ても分かる通り、JOINを使ってしまった方が、明らかに楽です。
だから、使えるものなら、JOINを使いたいところです。
大規模システムでは、JOINが使えない?
大規模なシステムでは、複数のテーブルをひとつのデータベースにまとめて置いておくのは効率が悪い場合があります。
データベースのサイズが大きくなると、すべてのデータがメモリに乗り切らずに、HDDへのアクセスが増加し速度が極端に低下するためです。
そこで、friendテーブルとcommentテーブルを別々のデータベースサーバに置くようにして解決する方法があります。(パーティショニングと言います。)
しかし、この状態では2つのテーブルが別のサーバにあってJOINが使えないので、「JOINを使わないで友人のコメントを取得する」方法が採用されます。
まとめ
以上をまとめると、こうなります。
テーブルを複数のサーバに分散させて置く場合は、JOINしない。
すべてのテーブルがひとつのデータベースサーバに置かれているような小規模で簡単なシステムでは、JOINすればいい。
コメント