MySQL同结构表执行DISTINCT date仅返回单个值的异常问题
问题背景
两张结构完全一致的表,字段定义:
date (date) title (varchar 275)
均包含2021-01-01至2021-12-31的日期数据。
在table1执行查询:
SELECT DISTINCT date FROM table1 WHERE date IN ('2021-01-02', '2021-01-04')返回预期结果:
2021-01-02 2021-01-04在table2执行相同查询时,仅返回IN列表中的最早日期:
执行SELECT DISTINCT date FROM table2 WHERE date IN ('2021-01-04', '2021-01-06')仅返回2021-01-04,更换任意日期范围均只返回最早值,表现类似添加了LIMIT 1。补充测试:移除DISTINCT后,
SELECT date FROM table2 WHERE date IN ('2021-01-04', '2021-01-06')可返回包含重复值的正确结果,但加回DISTINCT后依旧异常。
排查方向
对比两张表的建表语句,重点检查table2的
date字段是否存在异常索引或约束:用SHOW CREATE TABLE table2;和table1的建表语句对比,查看是否有唯一索引、函数索引等可能干扰DISTINCT逻辑的设置,尤其是索引是否损坏(比如唯一索引存在重复数据的异常情况)。验证table2的
date字段实际存储值:执行SELECT DISTINCT CAST(date AS CHAR) FROM table2 WHERE date IN ('2021-01-04', '2021-01-06');,查看字符串形式的日期值,确认是否存在肉眼不可见的字符、格式异常(虽然date类型本身不存时间,但需排除隐性转换问题)。对比两张表的查询执行计划:用
EXPLAIN SELECT DISTINCT date FROM table2 WHERE date IN ('2021-01-04', '2021-01-06');和table1的执行计划对比,检查优化器是否选择了不同的执行路径——比如table2是否走了某个索引导致提前终止遍历,而table1采用全表扫描或正常索引扫描。更新table2的统计信息并检查数据完整性:执行
ANALYZE TABLE table2;(MySQL)或对应数据库的统计信息更新命令,解决统计信息过时导致的优化器决策错误;同时用CHECK TABLE table2;检查是否存在数据页损坏。检查会话级参数差异:对比查询两张表时的会话参数,比如执行
SHOW VARIABLES LIKE '%collation%';、SHOW VARIABLES LIKE '%date_format%';,确认是否有排序规则、日期格式等参数影响了DISTINCT的去重逻辑。
内容的提问来源于stack exchange,提问作者mr_mooo_cow

