写在前面
公司需要对一些查询较慢的sql进行优化,这篇文章记录我从网上查到的资料并付诸实践的总结。
解决思路
针对sql语句优化,添加索引是行之有效但不是唯一的解决角度,我们可以尝试以下科学且专业的解决角度:
-
回归设计表层面,数据类型选择是否合理;
尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。这是因为引擎在处理查询和连接时会逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了。
应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:
select id from table where no is null
可以在no 上设置默认值0,确保表中no 列没有null值,然后这样查询:
select id from table where no = 0 -
大表碎片的整理是否完善;
略
-
表的统计信息是不是准确的;
略
-
审查表的执行计划,判断字段上面有没有合适的索引;
善用 EXPLAIN 查看SQL执行计划
type:连接类型。 system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL ,一般来说,得保证查询至少达到range级别,最好能达到ref。
key:使用到的索引名。如果没有选择索引,值是NULL。可以采取强制索引方式
key_len:索引长度
rows:扫描行数。该值是个预估值
extra:详细说明。注意常见的不太友好的值有:Using filesort, Using temporary -
针对索引的选择性,建立合适的索引
对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。
组合索引要服务最左原则(自行百度) -
书写语句的优化
or 、in | not in 、is null | is not null、!=、<>,使用时并不是完全不走索引 建议减少使用
exists的使用
select no from a where no in(select no from b)
用下面的语句替换:
select no from a where exists(select 1 from b where no=a.no)union的使用
应尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描,如:
select id from table where no =10 or no =20
可以这样查询:
select id from table where no =10
union all
select id from table where no =20
感谢
更多详情请移步
https://blog.csdn.net/weixin_42018518/article/details/89336888
https://blog.csdn.net/qq_32002253/article/details/86772940