txqz memo

where 句に関数を使うとインデックスが使われない罠

MySQL 4.1 リファレンスマニュアル の 「日付と時刻関数」には、

このクエリでは、過去 30 日以内の日付の date_col 値を持つすべてのレコードが選択されます

として

SELECT something
 FROM tbl_name
 WHERE TO_DAYS(NOW()) - TO_DAYS(date_col) >= 30;

という SQL 文が紹介されているけれども、これって INDEX が使われないわけで。

30日前の日付が他で分かるなら、それを BETWEEN で指定してあげれば、type が range なインデックスが使われる。だから、たとえば

SELECT something
 FROM tbl_name
 WHERE date_col BETWEEN
  DATE_FORMAT(DATE_ADD(NOW(), INTERVAL -30 DAY), '%Y-%m-%d 00:00:00') AND
  DATE_FORMAT(NOW(), '%Y-%m-%d 23:59:59');

とすればインデックスを使いつつ過去30日以内レコードを選択できるかなと思った。まぁ、データの量によっては無理してインデックスを使う必要もないわけなのだけれども。