应使用>= AND

WHERE子句中用BETWEEN还是>= AND 更安全?
直接用BETWEEN查created_at或last_login_time字段,容易漏掉毫秒级数据或跨天边界值。MySQL的BETWEEN是闭区间,而业务上“2024-01-01到2024-01-07”通常指包含0点起、不包含下一个周期的0点——即2024-01-01 00:00:00 ≤ x 2024-01-08 00:00:00。
推荐写法:
DATETIME
- 执行
SELECT @@time_zone, @@system_time_zone确认服务端时区 - 用
SELECT UNIX_TIMESTAMP('2024-01-01 00:00:00'), FROM_UNIXTIME(1704067200)验证时间戳与字符串互转是否符合预期 - 如果业务全在单一时区,建议把字段类型改为
DATETIME,避免隐式转换干扰
如何定义“活跃用户”?别只看last_login_time
单纯查登录时间可能漏掉行为型活跃用户(比如只刷API、提交表单但没走登录页)。真实场景中常需组合判断:
- 有
last_action_time字段就优先用它(含页面访问、按钮点击等埋点时间) - 没有的话,可联查日志表:
JOIN user_behavior_log ON u.id = log.user_id WHERE log.created_at BETWEEN ... - 注意加
DISTINCT u.id,避免同一用户多次行为被重复计数 - 如果数据量大,务必确保
created_at或last_login_time字段上有索引,否则范围扫描极慢
查询性能卡在几秒以上?先看执行计划里的type和key_len
跑EXPLAIN SELECT ... WHERE last_login_time >= ? AND last_login_time ,重点关注:<ul>
<li>
<code>type是不是range(理想),而不是ALL(全表扫)
key_len是否匹配索引字段长度(比如TIMESTAMP索引的key_len应为4或5字节,取决于是否允许NULL)(status, last_login_time)),但WHERE里没带status条件,索引可能失效FORCE INDEX (idx_last_login)强制走时间索引,但治标不治本时间范围检索最麻烦的不是语法,而是字段类型、时区、业务定义三者没对齐。哪怕SQL写对了,只要其中一环错位,结果就不可信。











