MySQLのDATE_FORMAT関数をWHERE文で使うと激烈に遅かった

※以前別の場所で書いた文章を備忘的に書き記しておきます。

【投稿年月日】2012-10-04 【ジャンル】PHP/MySQL | 提供サービス

 MySQLには「DATE_FORMAT」という便利な関数があります。実際、結構使っていたりします(「MysqlのDATE_FORMAT関数をもっと早く知っていれば」参照)。
 ところが「DATE_FORMAT」をWHERE文で使うと、場合によっては激烈に遅くなることが分かりました。

 弊社が運営する「競売物件研究所」では競売物件の入札情報を提供していますが、入札最終日の17時をもって詳細情報の提供を終了することにしています。そのため、
<?php
 $query = 'SELECT field_id, field_date FROM table_main WHERE DATE_FORMAT(field_date,"%Y-%m-%d %H:%i:%s") >= "'.date("Y-m-d H:i:s", strtotime("-17 hour")).'"';
 $result = mysql_query($query)
 $nums = mysql_num_rows($result);7
?>
のように記述していました。
 ところがこれでは速度がでません。EXPLAINで確認してみると、「Extra」で「Using filesort」と「Using temporary」が出てきます。原因を探っていくと、どうやら「DATE_FORMAT」をWHERE文で使うと正規化されない場合があるようです。

 少し考えた末、以下のような記述に変更しました。
<?php
 $add = (date("H")>=17) ? "" : "=";
 $query = 'SELECT field_id, field_date FROM table_main WHERE field_date >'.$add.' "'.date("Y-m-d").'"';
 $result = mysql_query($query)
 $nums = mysql_num_rows($result);
?>
 これで「Extra」から「Using filesort」と「Using temporary」は見事に消え、MySQLの速度が飛躍的に速くなりました。DATE_FORMAT関数をWHERE文で使うことのリスクをもっと早く知っていれば。。

 ついでに「競売物件研究所」の告知を少々。
 利用されている方からの要望があったので、以下の3つの新機能を実装しました。
  1. 開札スケジュールの新設。
  2. 検索項目に「種別・地目」を追加。([例] 東京地方裁判所[店舗]の競売物件情報
  3. 検索項目に「用途地域」を追加。([例] 東京地方裁判所[近隣商業地域]の競売物件情報
 これで、ますます使いやすくなったと思います。

EDIUNET | PHP/MySQL | 独り言 | 提供サービス | JavaScript