对字段使用函数会导致索引失效,如YEAR(create_time)=2023;应改写为create_time>='2023-01-01' AND create_time

WHERE 条件里对字段用函数
这是最常导致索引失效的操作。比如写 WHERE YEAR(create_time) = 2023,哪怕 create_time 有索引,MySQL 也无法走索引范围扫描,只能全表扫描。
正确做法是把函数移到右边,让左边保持纯列名:
WHERE create_time >= '2023-01-01' AND create_time- 如果必须按年月分组统计,优先考虑在应用层或用生成列(MySQL 5.7+)加索引
- PostgreSQL 中
EXTRACT(YEAR FROM create_time)同样会跳过索引,处理方式类似
SELECT * 在大宽表 + 分页场景下
当表有 50+ 字段、单行超 10KB,而业务只读其中 3 个字段时,SELECT * 会让网络传输、内存拷贝、临时表排序成本陡增,尤其配合 LIMIT 10000,20 这类深分页时更明显。
实操建议:
- 明确写出需要的字段,如
SELECT id, title, updated_at - 深分页改用游标(cursor-based pagination):用上一页最后的
updated_at和id作为下一页查询条件 - 避免在
ORDER BY字段上存在大量重复值(比如多个记录status = 'done'),否则ORDER BY + LIMIT可能因排序不稳导致漏数据
JOIN 时没加 ON 条件或条件写错
漏写 ON 会变成笛卡尔积,1 万行 × 1 万行 = 1 亿行中间结果;写错条件(比如用 = 比较 NULL 值、或类型不一致隐式转换)则可能让优化器误判执行计划。
“定海神真”免费效益网站是NITC网络营销服务中心经历3年多时间研发的历作,汇聚了15年的网站开发经验及8年网络营销经验。系统简单易用,界面精美,体验度高,对SEO优化也有良好的效果,而且永久免费。唯一缺陷就是主题界面只有50多个,但NITC开放了主题结构教程,懂DIV+CSS的网页设计人员很容易开发出自己喜欢的网页。NITC网站系统是中小企业网站营销的最佳
检查要点:
- 所有
JOIN必须显式带ON,禁止依赖WHERE补条件(尤其外连接) - 确认关联字段类型完全一致:
user_id INT和log.user_id VARCHAR会导致索引失效 + 类型转换开销 - 用
EXPLAIN看type是否为ALL或index,rows是否远超预期
ORDER BY + LIMIT 没覆盖索引
例如 SELECT * FROM orders WHERE status = 'paid' ORDER BY created_at DESC LIMIT 20,如果只有 status 单列索引,MySQL 仍需回表排序;若建了 (status, created_at) 联合索引,就能直接索引扫描 + 索引有序性取前 20 条。
关键原则:
- 联合索引顺序要匹配查询模式:等值条件字段在前,排序字段紧随其后
- 如果同时有多个等值条件(如
WHERE a=1 AND b=2),把区分度高的字段放前面 -
ORDER BY中混用 ASC/DESC(如ORDER BY a ASC, b DESC)在 MySQL 8.0 之前无法用索引排序,需升级或调整逻辑
真正卡住 SQL 性能的,往往不是复杂算法,而是这些看似无害的写法。每一条都容易被忽略,但叠加起来会让 QPS 断崖下跌——尤其是上线后流量一上来,慢查询日志里全是它们的名字。









