BETWEEN字段必须置于复合索引最右位,因范围查询使右侧字段失效;等值条件在前、BETWEEN在后,如(user_id, create_time);DATE类型BETWEEN安全,DATETIME宜用左闭右开写法。

复合索引中BETWEEN字段必须放在最右位
MySQL 的复合索引遵循最左前缀原则,而 BETWEEN 是典型的范围查询操作——一旦索引中某个字段用于范围条件(如 price BETWEEN 100 AND 500),其右侧所有字段都无法被索引有效利用。所以,BETWEEN 字段只能放在复合索引的末尾。
常见错误是把时间或价格字段放前面,比如创建 (create_time, user_id) 索引后执行:SELECT * FROM orders WHERE create_time BETWEEN '2024-01-01' AND '2024-01-31' AND user_id = 123;此时 user_id 完全无法走索引。
- 正确顺序:等值字段在前,
BETWEEN字段在后,例如(user_id, create_time) - 如果查询同时有多个等值条件(
status = 'paid',region = 'cn'),优先把选择性高(基数大、重复值少)的字段放左边 - 若业务中
user_id和status都常单独查,不要强行塞进一个复合索引,宁可建两个单列索引
DATE vs DATETIME字段的BETWEEN写法直接影响索引效果
对 DATETIME 或 TIMESTAMP 字段直接写 BETWEEN '2024-09-28' AND '2024-09-29',MySQL 会补成 '2024-09-28 00:00:00' 到 '2024-09-29 00:00:00',导致漏掉 9 月 29 日全天数据——这不是索引没生效,而是逻辑错误。
更安全、更利于索引扫描的写法是左闭右开:create_time >= '2024-09-28' AND create_time < '2024-09-30'
- 避免手动拼
'23:59:59',秒级精度易出错,且不兼容微秒字段 - 如果字段类型是
DATE(无时间部分),BETWEEN '2024-09-28' AND '2024-09-29'是安全的,等价于覆盖两天整日 - 任何在
BETWEEN左侧加函数的操作(如DATE(create_time) BETWEEN ...)都会让索引完全失效
EXPLAIN验证时重点看type和key字段
执行 EXPLAIN 是判断复合索引是否起效的唯一可靠方式。关键不是“有没有用索引”,而是它是否以高效方式使用了索引。
理想输出应包含:type: range(表示走了索引范围扫描)key: idx_user_time(命中你建的复合索引名)rows 值远小于表总行数
- 如果
type是ALL,说明全表扫描,检查是否漏建索引或条件写了函数 - 如果
key是NULL,说明优化器放弃使用索引,可能因统计信息过期,可尝试ANALYZE TABLE orders - 注意
Extra字段:出现Using filesort或Using temporary意味着排序/分组未走索引,需考虑覆盖索引或调整ORDER BY字段顺序
覆盖索引能绕过回表,但字段顺序不能乱
当查询只涉及索引字段(如 SELECT user_id, create_time, amount FROM orders WHERE user_id = 123 AND create_time BETWEEN ...),可建覆盖索引减少 I/O。但要注意:覆盖索引仍是复合索引,仍要遵守等值在前、范围在后的顺序。
错误示例:CREATE INDEX idx_cover ON orders(create_time, user_id, amount) —— 即使 user_id 是等值条件,因 create_time 在前,该索引对 user_id = ? AND create_time BETWEEN ... 查询无效。
- 正确覆盖索引:如查询固定返回
user_id,create_time,amount,应建(user_id, create_time, amount) - 字段越多,索引体积越大,写入性能越低,别盲目堆字段;只加真正 SELECT 中出现的列
- 如果查询还带
ORDER BY create_time,该复合索引天然支持排序,无需额外排序步骤
实际中最容易被忽略的是:复合索引字段顺序不是按“查询里写的顺序”,而是按“条件类型+选择性”决定的;哪怕 SQL 里先写 create_time 再写 user_id,只要 user_id 是等值、create_time 是 BETWEEN,索引就必须是 (user_id, create_time)。


















