15

mysql が次のように使用して datetime をクエリできることがわかりました。

like '2013-06-12%'

インデックスは使えないと思います。私はそれをグーグルで調べましたが、そのような主題を直接見つけることはできません。したがって、3308614 レコードのテーブルを使用したテストがあります。最初の SQL:

SELECT * FROM subscription t WHERE DATE(t.active_time) = '2013-06-30';

この SQL がインデックスを使用できないことはわかっており、結果を取得するのに 4 秒かかります。2 番目の SQL:

SELECT * FROM subscription t WHERE t.active_time LIKE '2013-06-30%';

インデックスが使えるかどうかはわかりませんが、4秒もかかります。3 番目の SQL:

SELECT * FROM subscription t WHERE t.active_time > '2007-11-30' AND t.active_time < '2007-12-01';

3 番目の SQL がインデックスを使用できることはわかっており、0.016 秒かかります。

だから、mysqlは最初にdatetimeフィールドを文字列に変換し、その文字列をlikeコマンドに送信する必要があるため、datetimeフィールドを照会するときに「like」はインデックスを使用できないと思います。これは正しいです ?

4

2 に答える 2

19

t.active_timeそのタイプがであると仮定するとDATETIME

次のクエリは、関数呼び出しのためにインデックスを使用できません。と比較する前に、すべてactive_timeをオンザフライで値に変換する必要があります。この文字列は最初に値に変換されますが、これはクエリの最初に 1 回だけ行われます。DATE'2013-06-30'DATE

SELECT * FROM subscription t WHERE DATE(t.active_time) = '2013-06-30';

2 番目のクエリでも、同様の理由でインデックスを使用できません。あなたは実際に文字列比較を行っています(LIKE演算子のため)。すべてのactive_time値はオンザフライで文字列に変換されます。

SELECT * FROM subscription t WHERE t.active_time LIKE '2013-06-30%';

インデックスを使用できるのは最後の 1 つだけです。この場合、and演算子で許可されているため、文字列'2007-11-30'and'2007-12-01'がキャストされます。DATETIME<>

SELECT * FROM subscription t WHERE t.active_time > '2007-11-30' AND t.active_time < '2007-12-01';

後者は=andBETWEEN演算子にも適用されます。

参考までに、演算子を使用してすべての型を文字列と比較できますがLIKE、暗黙の変換が必要なため、上記と同じ問題が発生します。

t.active_time = '2013-06-30''2013-06-30'が値にキャストされるためDATETIME、つまり が期待どおりに機能しません'2013-06-30 00:00:00'

于 2013-06-14T06:44:17.533 に答える
5

このような場合の代替手段の 1 つは、次のようにすることです。

SELECT *
FROM subscription t
WHERE t.active_time BETWEEN '2013-06-30 00:00:00' AND '2013-06-30 23:59:59';

最終的に、その日のすべてのイベントを取得します。

于 2014-02-14T22:10:46.920 に答える