Web開発チームに、どのようにMySQLを使うべきかについて書いていたところ、これから共有する以下のリストを考えついた。「MySQLにとってよくないクエリとはどんなものか?」
- あらゆるクエリはよくない。どうしても必要な時だけクエリを送ること(ヒント : memcachedやRedisのようなキャッシュの仕組みを使おう)
たくさんの行にアクセスするクエリはよくない。以下のようにやろう(訳注 : プライマリキーをイコール指定したwhere句を使おう、の意)。
SELECT col1 FROM table1 WHERE primary_key_column=SOMETHING
あるいは最低でも以下のようにしよう(訳注 : インデックスが張られたカラムをイコール指定したwhere句を使おう、の意)。
secondary_key_column=SOMETHING
これがどうしても不可能なら、最低限必要な行だけにアクセスするようなクエリを作るよう努力しよう(最初の例のように0が理想だ)。
JOINを使ったクエリはよくない。JOINを使わなくていいよう、テーブルを非正規化しよう。例えば、元のクエリが以下の時、
SELECT t2.value FROM t2 JOIN t1 ON (t1.id=t2.tid) WHERE t1.orderdate=NOW()
orderdate
カラムをテーブルt1
から テーブルt2
にコピーして非正規化することで、クエリはこうなる。SELECT t2.value FROM t2 WHERE t2.orderdate=NOW()
第3正規系の熱狂的支持者は私をぶん殴るだろうが、これはパフォーマンスのためには必要なのだ。
集合関数を使うクエリはよくない。多数の行に渡る
SUM
,AVG
,MIN
,MAX
関数を使っている場合、テーブルをまとめる前にこれらの値を計算するか、最悪でも扱う行数を最小化しよう。日ごと、週ごと、月ごと、とにかく何でもサマリーテーブルを作ればよい。INSERT .. ON DUPLICATE UPDATE ...
がとても役に立つはずだ。