MySQL5.1でDATETIME列にインデックスを作成した場合に範囲条件の結果が不一致

事象

MySQL5.1でDATETIME列にインデックスを作成したら、範囲条件が正しく動作しなくなった。
ちょっと複雑なので順を追って説明します。


1.下記のようなテーブルを作成した。

exampleテーブル

列名 データ型 制約など
id INT PRIMARY KEY,AUTO_INCREMENT
name VARCHAR(50)
update DATETIME NOT NULL

データ

id name update
1 いち 2010-03-09 23:59:59
2 2010-03-10 00:00:00
3 さん 2010-03-10 23:59:59
4 2010-03-11 00:00:00


2. update列にインデックスがない状態で、update列を範囲条件で絞り込む。以下のSQLを実行。

SELECT id,name,update FROM example WHERE update >= '2010-03-10 00:00:00.0'

java.sql.Timestampとのマッピング上、後ろに '.0' をつけてます。なお、mysqlコマンドで確認しました。

結果:OK 3件

id name update
2 2010-03-10 00:00:00
3 さん 2010-03-10 23:59:59
4 2010-03-11 00:00:00


3. update列にインデックスを作成


4. 再度、2.のSQLを実行する。

SELECT id,name,update FROM example WHERE update >= '2010-03-10 00:00:00.0'

結果:NG 2件
id:2の行が取得できていない。

id name update
3 さん 2010-03-10 23:59:59
4 2010-03-11 00:00:00


5. 2.のSQLで、出力列をupdate列のみに絞り込んで実行すると成功。

SELECT update FROM example WHERE update >= '2010-03-10 00:00:00.0'

結果:OK 3件

update
2010-03-10 00:00:00
2010-03-10 23:59:59
2010-03-11 00:00:00


6. 2.のSQLで、update列の範囲指定から'.0'を除去すると成功。

SELECT id,name,update FROM example WHERE update >= '2010-03-10 00:00:00'

結果:OK 3件

id name update
2 2010-03-10 00:00:00
3 さん 2010-03-10 23:59:59
4 2010-03-11 00:00:00

いろいろ調べてみた。

  • 範囲条件でも、以上(update >= '2010-03-12 00:00:00.0')の場合のみ問題が発生する。
  • 以下(update <= '2010-03-12 00:00:00.0')の場合は正しく動作する。

対処

STR_TO_DATEを使用することで解決。
update >= STR_TO_DATE('2010-03-12 00:00:00.0', '%Y-%m-%d %H:%i:%s.0')で正しく動作した。