推荐用 WHERE create_time >= CURDATE() AND create_time < DATE_ADD(CURDATE(), INTERVAL 1 DAY) 实现当日查询,避免函数作用于字段导致索引失效,兼顾性能与可读性。

用 DATE() 或 CURDATE() 获取当天日期
直接比较日期字段和当前日期时,别用 NOW() 带时间部分的值,否则可能漏掉当天 00:00–23:59 的记录。MySQL 中推荐用 CURDATE()(返回 YYYY-MM-DD 格式),或 DATE(NOW()) 显式截断时间。
常见错误是写成 WHERE create_time = NOW() —— 这几乎永远不匹配,因为 create_time 很少精确到秒级且和 NOW() 完全一致。
- 正确写法:
WHERE DATE(create_time) = CURDATE() - 更高效写法(能走索引):
WHERE create_time >= CURDATE() AND create_time - 注意:如果
create_time是DATETIME或TIMESTAMP类型,用范围查询比DATE()函数包裹更利于索引利用
查最近7天(含今天)用 DATE_SUB() + 范围查询
“最近7天”通常指从今天开始往前推7天(含今天共7天),即 [T-6, T](T 为今天 00:00)。但业务中常理解为“过去7×24小时”,需按需选择逻辑。
推荐统一用闭区间左包含、右包含的写法,避免边界遗漏:
- 标准7天(含今天):
WHERE create_time >= DATE_SUB(CURDATE(), INTERVAL 6 DAY) AND create_time - 过去7×24小时(更严格):
WHERE create_time > DATE_SUB(NOW(), INTERVAL 7 DAY) - PostgreSQL 用户请换用:
WHERE create_time >= CURRENT_DATE - INTERVAL '6 days' - SQLite 用户用:
WHERE create_time >= date('now', '-6 days')
不同数据库的时间函数差异要点
同一语义在不同数据库里函数名、参数格式、默认时区行为都不同,硬搬 MySQL 写法到 PostgreSQL 或 SQL Server 会报错或结果偏差。
- MySQL:
CURDATE()、DATE_SUB(CURDATE(), INTERVAL 6 DAY) - PostgreSQL:
CURRENT_DATE、CURRENT_DATE - INTERVAL '6 days'(注意单引号和单位复数) - SQL Server:
GETDATE()配合DATEADD(day, -6, CAST(GETDATE() AS DATE)) - Oracle:
TRUNC(SYSDATE)和TRUNC(SYSDATE) - 6(TRUNC去除时间部分) - 关键提醒:所有数据库中,对带时区的字段(如
TIMESTAMP WITH TIME ZONE)做比较前,务必确认时区上下文是否一致,否则WHERE条件可能跨天失效
性能陷阱:函数作用于字段会导致索引失效
写 WHERE DATE(create_time) = CURDATE() 看似简洁,但 DATE() 是对字段计算,MySQL 无法使用 create_time 上的 B-tree 索引,全表扫描风险高。
真正要兼顾可读性和性能,优先选范围查询,哪怕多写几个字符:
- ✅ 推荐:
WHERE create_time >= '2024-06-01' AND create_time (预计算好日期字符串,最稳) - ✅ 次选:
WHERE create_time >= DATE_SUB(CURDATE(), INTERVAL 6 DAY) AND create_time - ❌ 避免:
WHERE DAYOFYEAR(create_time) = DAYOFYEAR(NOW())或其他字段侧函数 - 验证方式:执行
EXPLAIN看key列是否非 NULL,rows是否显著小于表总行数
实际用的时候,先看字段类型、再定时间语义、最后挑对应数据库的写法——三个变量少一个,结果就可能不对。尤其上线前务必用真实数据量测下 EXPLAIN,别只在空表上试。

















