- SQL 优化的见解?
(面试时候先画饼凸显自己的实战能力)
对于MySQL层优化我一般遵从五个原则:
- 减少数据访问:设置合理的字段类型,启用压缩,通过索引访问等减少磁盘 IO。
- 返回更少的数据:只返回需要的字段和数据分页处理,减少磁盘 IO 及网络 IO。
- 减少交互次数:批量 DML 操作,函数存储等减少数据连接次数。
- 减少服务器 CPU 开销:尽量减少数据库排序操作以及全表查询,减少 CPU 内存占用。
- 利用更多资源:使用表分区,可以增加并行操作,更大限度利用 CPU 资源。
总结到 SQL 优化中,就如下三点:
- 最大化利用索引。
- 尽可能避免全表扫描。
- 减少无效数据的查询。
具体优化案例:
- 尽量避免在字段开头模糊查询,会导致数据库引擎放弃索引进行全表扫描
- 数量少可以直接用 like ‘%xx%’
- 数量大情况,建议引用 ElasticSearch、Solr,亿级数据量检索速度秒级
- 尽量避免使用 in 和 not in,会导致引擎走全表扫描
如果是连续数值,可以用 between 代替 如:
SELECT * FROM t WHERE id BETWEEN 1 AND 3
如果是子查询,可以用 exists 代替。 如:
— 不走索引 select from A where A.id in (select id from B); — 走索引 select from A where exists (select * from B where B.id = A.id);
- 尽量避免使用 or,会导致数据库引擎放弃索引进行全表扫描
- 可以用 union 代替 or,如:
SELECT FROM t WHERE id = 1 UNION SELECT FROM t WHERE id = 3
- 尽量避免在 where 条件中等号的左侧进行表达式、函数操作,会导致数据库引擎放弃索引进行全表扫描
- 查询条件不能用 <> 或者 !=
- where 条件没按最左前缀匹配原则来查找
- 隐式类型转换造成不使用索引
- order by 条件要与 where 中条件一致,否则 order by 不会利用索引进行排序
- 避免出现 select *
- 多表关联查询时,小表在前,大表在后
- 使用表的别名