mysql datetime field with index get a range 'like' vs. 'between and' performance

谁说我不能喝 提交于 2020-02-20 07:12:11

问题


I just find mysql can query datetime using like:

like '2013-06-12%'

I think it can not use the index. I Google it, but can not find such subject directly. So I have a test using a table with 3308614 records. The first SQL:

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

All we know this SQL can not use the index and it takes 4 seconds to get the result. The second SQL:

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

I don't know if it can use the index, but it takes 4 seconds too. The third SQL:

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

All we know the third SQL can use the index, and it takes 0.016 second.

So I think 'like' can not use the index when query the datetime field, because mysql should convert datetime field to string first and send the string to like command. Is this correct ?


回答1:


Assuming that t.active_time's type is DATETIME,

The following query cannot use an index because of the function call. All active_time must be converted on-the-fly to a DATE value before comparison with '2013-06-30'. This string is converted to a DATE value in the very first place, and this happens only once at the very beginning of the query.

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

The second query cannot use an index either for similar reasons. You are actually making a string comparison (because of the LIKE operator). All active_time values are converted to a string on-the-fly.

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

Only the last one can use an index. The strings '2007-11-30' and '2007-12-01' are cast to DATETIME in this case, because the < and > operators allow this.

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

The latter also applies to the = and BETWEEN operators.

For information, all types can be compared to a string with the LIKE operator, suffering from the same problem as described above, because of the implicit conversion it requires.

t.active_time = '2013-06-30' does not work as expected because '2013-06-30' is cast to a DATETIME value, that is to say '2013-06-30 00:00:00'.




回答2:


One alternative for such cases is to do something like this:

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

In the end you get all events from that day.



来源:https://stackoverflow.com/questions/17101436/mysql-datetime-field-with-index-get-a-range-like-vs-between-and-performance

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!