PEAK XOOPS - JOINよりIN in englishin japanese

Archive | RSS |
PHP
PHP : JOINよりIN
Poster : GIJOE on 2006-06-04 04:32:00 (9839 reads)

in englishin japanese
MySQLの特徴の一つに、「単純なクエリでは圧倒的に速いが、複雑なクエリだとそうでもない」が挙げられます。

そのため、LAMPアプリケーションの設計では、クエリの回数を抑えることよりも、各クエリをバラバラにして、なるべく単純なクエリにすることが、速度向上の近道のようです。

例えば、「カテゴリー対グループという権限設定のついたアイテムを検索する」なんてありがちなケースを考えます。


CREATE TABLE cat (
  `cid` int NOT NULL default 0,
  `name` varchar(255) NOT NULL default '',
  PRIMARY KEY (cid)
) TYPE=MyISAM ;

CREATE TABLE cat_perm (
  `cid` int NOT NULL default 0,
  `gid` int NOT NULL default 0,
  PRIMARY KEY (cid,gid)
) TYPE=MyISAM ;

CREATE TABLE item (
  `id` int NOT NULL default 0,
  `cid` int NOT NULL default 0,
  `name` varchar(255) NOT NULL default '',
  PRIMARY KEY (id),
  KEY (cid)
) TYPE=MyISAM ;


こんな構造の場合、SQL書きを得意としている人間は、ついつい、

SELECT item.* FROM item LEFT JOIN cat_perm ON cat_perm.cid=item.cid WHERE cat_perm.gid=1;

なんてクエリを発行しがちですが、少なくともMySQL的には効率が悪いのです。


SELECT cid FROM cat_perm WHERE gid=1;

として、いったんcidを一通り得てから、

SELECT * FROM item WHERE cid IN (cid一覧);

と2回に分けることで、実はとてもMySQLの効率は良くなります。

もちろん、「cidを一通り」得てIN用の文字列を用意する部分の実行効率がどれほどであるかによってトータルのパフォーマンス違ってくるでしょうが、ざっとベンチマークをとった限り、通常のLAMP環境では、やはり後者の方が速い、という結果が得られました。(「カテゴリー数」が増えて、INの部分がかなり長いケースでも結果は同じ)

実際のケースでは、アイテムに対するカテゴリーは十分に小さく、逆に、権限テーブルはずっと複雑になりがちなので、その差はもっと開くと思います。

JOINよりもIN

標語としても良くできてますね
--------------------
(2006/06/06追記)
このベンチマーク自体は問題ないのですが、比較する相手が悪いという指摘を受けました。
確かにその通りだったので、訂正記事の方も参照してください。


Related articles
Printer friendly page Send this story to a friend

Comments list

GIJOE  Posted on 2006/6/5 5:36
Quote:
これは、MySQLのJOINの設計がかなり悪いということなんでしょうか。
このあたり、どうなんでしょうね。
私もDB屋ではないので、単にベンチで測るくらいしかできないのですが。

Quote:
MySQLがPHPと違うサーバにある場合はちょっと事情が変わりそうですね。
このケースではほとんど問題にならないでしょうね。
クエリ1回が2回になるだけなので。

ループ展開みたいな形でのクエリ単純化だと、ネットワーク遅延とかが効いてきそうな気はしますが。
tohokuaiki  Posted on 2006/6/4 21:05
これは、MySQLのJOINの設計がかなり悪いということなんでしょうか。
MySQLがPHPと違うサーバにある場合はちょっと事情が変わりそうですね。
minahito  Posted on 2006/6/4 11:08
Quote:
こんな構造の場合、SQL書きを得意としている人間は、ついつい

これができません……;;
JOIN レベルですでにまともに使えない…… orz
Login
Username or e-mail:

Password:

Remember Me

Lost Password?

Register now!