index_mergeが起きる時と起きない時
あれ?MySQLは「1クエリに1インデックスしか使えない」んじゃなかったっけ?と思ったけど、5系からはインデックス結合最適化ってゆーのが行われるらしい。
http://dev.mysql.com/doc/refman/5.1/ja/index-merge-optimization.html
ただ問題なのが
あるキーでレンジスキャンが可能な場合、インデックス結合は考慮されません。
というところ。具体的に言うと、以下の①はOKだけど②はNG
-- ①これはgoodkey1,goodkey2でindex_mergeが行われる SELECT * FROM t1 WHERE (goodkey1 < 10 OR goodkey2 < 20); -- ②これはgoodkey1,goodkey2のindex_mergeは使用されずフルスキャンになっちゃう SELECT * FROM t1 WHERE (goodkey1 < 10 OR goodkey2 < 20) AND badkey < 30;
badkey<30が邪魔っすね。実際こういう系で起きました。
-- user_id:oreが絡むstatus:1(完了済)のレコードを検索 SELECT * FROM user_send WHERE (send_user = 'ore' OR recv_user = 'ore') AND status = 1;
status = 1をロジックで追加した瞬間クエリが激重に!!(こういうクエリって過去にもよく投げていたような気がするけど気のせいかな…?)
愚直にSELECT文を2回投げて結果をマージして対応しました。
Scalaだとこうか。(send_list ::: recv_list)