这种情况下的索引,十年老开发都说会失效?

83 阅读2分钟

这种情况下的索引,十年老开发都说会失效?

背景

​ 杭州某小公司二面,面试官说自己做开发十年了。问我这样一个场景,当前有一个表的字段类型是时间,这个字段建立了索引,然后如果只根据时间的前面部分,就比如,只根据年月来进行查询,索引会失效吗?大伙觉得会失效吗?

剖析问题

MySQL中时间字段类型,两种,datetime(包括时分秒)和date(只有年月日)。这个技术经理的问题,应该只针对datetime类型,因为对于date类型的话,只使用年月来进行查询的话,是会报错的。

使用日期字段的话,必须完整。否则报错如下:

[SQL]explain SELECT * FROM example_table2
WHERE event_date = '2024-07';
[Err] 1525 - Incorrect DATE value: '2024-07'

如果是使用datetime类型的话,可以只通过年月日进行查询,因为MySQL会默认帮我们填充时分秒:

SELECT * FROM example_table
WHERE event_time = '2024-07-02';

所以,十年老开发想问的问题有两种可能性:

第一种,datetime类型字段,只使用年月日会走索引吗?

证明

先让Chatgpt写个示例表,表中的字段是datetime类型,然后再插入一些数据。

CREATE TABLE example_table (
    id INT AUTO_INCREMENT PRIMARY KEY,
    event_time DATETIME,
    description VARCHAR(255)
);

CREATE INDEX idx_event_time ON example_table(event_time);

INSERT INTO example_table (event_time, description) VALUES 
('2024-07-01 12:00:00', 'Event 1'),
('2024-07-02 13:30:00', 'Event 2'),
('2024-07-03 15:45:00', 'Event 3'),
('2024-07-04 09:00:00', 'Event 4'),
('2024-07-05 18:20:00', 'Event 5');

查询语句:

explain SELECT * FROM example_table
WHERE event_time = '2024-07-02';

image-20240708132407970转存失败,建议直接上传图片文件

因为底层会默认添加0时0分0秒,所以如果我们只传入年月日的话,仍然会走索引进行查询。

第二种,对于字符串类型

对于字符串类型的字段,如果建立了索引,进行查询的时候,毋庸置疑,是肯定会走索引。

总结

给时间字段建立索引,然后截取时间的前半部分进行查询,这个问题本身就有歧义。对于日期字段来说,进行传值的时候,必须使用完整的数据,没有截取一说。

真实场景下,一般是使用like模糊查询,只要%不在最左边,索引就不会失效。