筛选当天新增数据应使用 current_date 配合范围查询:where created_at >= current_date and created_at
WHERE 条件里用 CURRENT_DATE 还是 NOW()?
筛选当天新增数据,核心是把时间字段和“今天”对齐。很多人直接写
NOW(),结果查不到数据——因为NOW()返回带时分秒的完整时间戳,而你的created_at字段可能精确到秒,但业务上“当天新增”只关心日期部分。
- 如果字段类型是
DATETIME或TIMESTAMP,推荐用CURRENT_DATE配合范围查询:WHERE created_at >= CURRENT_DATE AND created_at- 直接用
DATE(created_at) = CURRENT_DATE虽然语义清晰,但会阻止索引使用(DATE()是函数,无法走created_at上的索引)- PostgreSQL 用户注意:
CURRENT_DATE行为一致,但别用NOW()::date做等值判断,同样有索引失效风险MySQL 中 timestamp 字段自动更新会影响筛选吗?
会,而且容易被忽略。如果
created_at定义为TIMESTAMP DEFAULT CURRENT_TIMESTAMP,它默认按服务器时区存入;但如果你在连接层或应用里设置了不同时区(比如SET time_zone = '+08:00'),CURRENT_DATE和实际存储值可能跨天。
- 检查表定义:
SHOW CREATE TABLE your_table,确认created_at是否含ON UPDATE CURRENT_TIMESTAMP——这个只影响更新时间,不影响新增筛选- 更稳妥的做法:统一用 UTC 存储,查询时用
CONVERT_TZ(CURRENT_DATE, '+00:00', '+08:00')对齐(但不如直接在应用层处理时区清晰)- 简单场景下,优先确保数据库、连接、应用三端时区一致,否则
CURRENT_DATE和数据实际日期对不上PostgreSQL 怎么避免 to_char 导致全表扫描?
有人写
WHERE to_char(created_at, 'YYYY-MM-DD') = CURRENT_DATE::text,看着能跑通,但只要数据量一上来就变慢。因为to_char是计算型表达式,无法利用created_at的 B-tree 索引。
- 正确姿势仍是范围查询:
WHERE created_at >= CURRENT_DATE AND created_at- 如果你常用这个条件,可以建表达式索引:
CREATE INDEX idx_created_date ON your_table ((created_at::date)),但注意这索引只对created_at::date = CURRENT_DATE有效,仍不如原生范围查询通用- 小心
BETWEEN:写成created_at BETWEEN CURRENT_DATE AND CURRENT_DATE + INTERVAL '1 day' - INTERVAL '1 second'逻辑正确,但可读性差,且易漏掉最后一秒的数据(尤其高并发插入时)字段是字符串类型(如 '2024-05-20 14:23:01')怎么办?
这是历史包袱常见情况。不能直接比大小,字符串比较会出错(比如
'2024-05-20 9:00:00'>'2024-05-20 10:00:00',因为 '9' > '1')。
- 先转成时间类型再比较:MySQL 用
STR_TO_DATE(created_at, '%Y-%m-%d %H:%i:%s'),PostgreSQL 用created_at::timestamp(前提是格式严格匹配)- 但每次查询都转换,性能差,且无法索引加速
- 长期解法:加一个生成列(MySQL 5.7+)或物化视图(PG),并建索引。例如 MySQL:
ADD COLUMN created_at_ts TIMESTAMP GENERATED ALWAYS AS (STR_TO_DATE(created_at, '%Y-%m-%d %H:%i:%s')) STORED,然后在created_at_ts上建索引时区、字段类型、索引有效性这三点卡住绝大多数人,不是语法不会,而是没意识到数据“看起来像今天”和数据库“认定是今天”之间隔着一层隐式转换或时区偏移。











