sql性能优化需避免索引失效、深分页、低效join和count瓶颈:where禁用函数/计算,order by+limit须匹配索引,join用小表驱动并确保类型一致,count(*)宜用覆盖索引或计数表,索引价值取决于字段值分布。

WHERE 条件没走索引,查得慢还爆内存
不是所有 WHERE 都能用上索引。常见坑是写成 WHERE SUBSTRING(phone, 1, 3) = '138' 或 WHERE status + 0 = 1 —— 这类表达式会让索引失效,引擎被迫全表扫描。
实操建议:
- 用
EXPLAIN看type是否为ALL(全表扫描)或index(索引全扫),理想是ref或range - 避免在索引列上做函数、计算、隐式类型转换;手机号查前缀就建
phone_prefix字段并单独索引 - 字符串比较注意 collation,
utf8mb4_0900_as_cs和utf8mb4_general_ci对大小写和性能影响不同
ORDER BY + LIMIT 在大数据集上卡死
比如 SELECT * FROM orders ORDER BY created_at DESC LIMIT 10,表面看只取 10 行,但 MySQL 可能先排序全部 5000 万行再截断。
实操建议:
- 确保
ORDER BY字段有索引,且和LIMIT组合使用时,索引顺序匹配(如INDEX(created_at)支持ORDER BY created_at DESC) - 分页深了别用
OFFSET,改用游标:记下上一页最后一条的created_at和id,下一页查WHERE created_at - 如果业务允许,加
WHERE created_at > DATE_SUB(NOW(), INTERVAL 7 DAY)先缩小范围,再排序
JOIN 多张大表,执行计划崩了
三张千万级表 JOIN,没控制好驱动表和连接条件,容易触发临时表 + 文件排序,磁盘 IO 拉满,查询超时。
95Shop可以免费下载使用,是一款仿醉品商城网店系统,内置SEO优化,具有模块丰富、管理简洁直观,操作易用等特点,系统功能完整,运行速度较快,采用ASP.NET(C#)技术开发,配合SQL Serve2000数据库存储数据,运行环境为微软ASP.NET 2.0。95Shop官方网站定期开发新功能和维护升级。可以放心使用! 安装运行方法 1、下载软件压缩包; 2、将下载的软件压缩包解压缩,得到we
实操建议:
- 用
EXPLAIN FORMAT=JSON看join_buffer_size是否被撑爆,以及哪张表是驱动表(table列最先出现的那张) - 小表驱动大表:把过滤后只剩几百行的表放
FROM,大表放JOIN右侧;必要时用STRAIGHT_JOIN强制顺序 - 连接字段类型必须严格一致(比如都是
BIGINT UNSIGNED),否则隐式转换让索引失效 - 避免
SELECT *,只查真正需要的字段,减少网络传输和临时表体积
统计 COUNT(*) 卡住,或者结果不准
对亿级表跑 COUNT(*),InnoDB 要遍历主键索引,不是 O(1);而用缓存值或近似统计又可能漏数据。
实操建议:
- 精确计数且频率低:加覆盖索引(如
INDEX(dummy) USING BTREE,字段设为常量TINYINT DEFAULT 0),让引擎扫更小的二级索引 - 高频统计需求:用单独的计数表,每次
INSERT/DELETE后用事务同步更新,别依赖实时COUNT - 接受误差:MySQL 8.0+ 可开
innodb_stats_persistent并定期ANALYZE TABLE,配合SELECT table_rows FROM information_schema.tables查估算值
真正难的不是加索引,而是判断「这列值的分布是否值得建索引」——比如性别字段只有两个值,加索引反而拖慢写入;而用户 ID 的唯一性高,哪怕没在 WHERE 出现,也可能被优化器选作连接路径。这类权衡没法靠规则穷举,得看 EXPLAIN 输出里的 rows 和 filtered 实际值。









