SQL最近N天数据查询_时间条件设计技巧

4次阅读

SQL 最近 N 天数据查询_时间条件设计技巧

查最近 N 天的数据,关键不在写 SQL 本身,而在准确理解业务时间字段含义、时区影响和索引有效性。直接用 WHERE create_time >= DATE_SUB(NOW(), INTERVAL N DAY) 很常见,但容易踩坑。

明确时间字段类型和存储逻辑

MySQL 中常见时间字段有 DATETIMETIMESTAMPINT(时间戳秒数)。不同字段对函数处理和索引支持差异大:

  • DATETIME:不带时区,建议用 DATE_SUB(NOW(), INTERVAL N DAY),且确保该字段有索引
  • TIMESTAMP:自动转为 UTC 存储,查询时需注意连接会话时区(SET time_zone = '+08:00'),否则可能漏数据
  • INT 存秒级时间戳:推荐用 WHERE ts >= UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL N DAY)),避免在字段上用函数(如 FROM_UNIXTIME(ts))导致索引失效

避免函数作用于索引列

写条件时,让计算发生在右边,别把函数套在左列上。以下写法会让 create_time 索引失效:

❌ 错误示例:WHERE DATE(create_time) >= '2024-06-01'

正确做法是推算出时间边界,直接比较原始值:

✅ 推荐写法:WHERE create_time >= '2024-06-01 00:00:00' AND create_time

或者用区间函数(MySQL 8.0+):WHERE create_time BETWEEN '2024-06-01' AND '2024-06-01 23:59:59',但注意 BETWEEN 是闭区间,精度要对齐。

考虑业务“最近 N 天”的真实定义

“最近 N 天”可能是:

  • 自然日 :从今天 0 点往前推 N 天(如今天 6 月 5 日,N=3 → 查 6 月 2 日 00:00 起的数据),用 DATE_SUB(CURDATE(), INTERVAL N DAY)
  • 滚动 N×24 小时 :从当前时刻倒推 N 天(如现在是 6 月 5 日 14:30,N=3 → 查 6 月 2 日 14:30 起的数据),用 DATE_SUB(NOW(), INTERVAL N DAY)
  • 按业务日切分 :某些系统以早 6 点或晚 8 点为日切分点,需手动调整基准时间,例如:DATE_SUB(DATE_ADD(NOW(), INTERVAL 6 HOUR), INTERVAL N+1 DAY) + INTERVAL 6 HOUR(适配早 6 点日切)

加索引与执行计划验证

即使条件写对,没索引也慢。确认执行计划是否走索引:

EXPLAIN SELECT * FROM orders WHERE create_time >= DATE_SUB(NOW(), INTERVAL 7 DAY);

重点看 type 是否为 range 或更好,key 是否显示用了索引名。若显示 type=ALL,说明全表扫描——检查是否索引缺失、字段类型不匹配,或 WHERE 中对列用了函数。

text=ZqhQzanResources