寻根溯源,你有哪些优化和排查性能异常的SQL秘籍?
sql优化
避免使用select *,只列出需要用到的列用Union all 代替 union union关键字可以获得排除重复项之后的数据,而使用Union all可以获得所有数据,包含重复的数据,union排重时需要遍历、排序和比较,因此union all更省时间
3.小表驱动大表
用小表的数据集驱动大表的数据集,in关键字会优先执行in里面的子查询语句,然后再执行in外面的,因此如果in里面的数据量更少,作为条件查询的速度更快;
exists会先执行exists左边的语句,即主查询语句,把它作为条件去和右边的语句匹配,如果匹配的上,则可以查询出数据,匹配不上数据就被过滤掉了;总结:in适用于左边大表,右边小表,exists适用于左边小表,右边大表,其核心思想都是用小表驱动大表;4.批量操作
insert into order(id,code,user_id) values(123,'001',100);-->insert into order(id,code,user_id) values(123,'001',100),(124,'002',100),(125,'003',101);
这样只需请求一次数据库,sql性能会提升很多,数据量越多,提升越大;不建议一次批量操作太多的数据,需要把握一个度;5.多用limit
查询某些数据的前几条,先查询出所有数据集合,然后使用limit获取前几个元素数据;注意在删除或修改数据时,为了防止误操作,导致删除或修改了不相干的数据,也可以在后面加上limit6.in中值太多
用limit做限制
7.增量查询
有时候需要通过远程接口查询数据,然后同步到另外一个数据库,此时直接获取所有数据然后同步过去,查询性能会非常差;
因此需要将数据按照id和时间升序,每次只同步一批数据,每次同步完成后,保留这些数据中最大的id和时间,给同步下一批数据的时候用
8.高效的分页
列表页在查询数据时,为了避免一次返回过的数据影响接口性能,一般会对查询接口做分页处理,还能使用limit与between分页9.用连接查询代替子查询
子查询可以用in关键字实现,一个查询语句的条件落在另一个select查询结果中,先运行最内层的语句,再运行外层语句,优点是简单、结构化;
但在执行子查询时,需要创建临时表,查询完毕后需要删除这些临时表,有一些额外的性能消耗,因此可以修改成连接查询
10.join的表不宜过多
阿里巴巴开发手册规定,join的表最多不超过三个,但在实际业务中,join的表要根据实际情况而定,尽量越少越好;
11.join时要注意
left join:求两个表的交集外加左边剩下的数据 inner join:求两个表交集的数据
inner join关联时,会自动选择两张表中的小表去驱动大表,因此性能上不会有太大问题,
而使用left join关联时,默认使用left join左边的表去驱动他右边的表,如果左边的表数据过多时,就会出现性能问题,因此左边用小表,右边用大表,能用inner join就少用left join
12.控制索引的数量
索引能显著提升sql查询的速度,但并非越多越好,索引需要一定的空间且会有性能消耗,但表的索引数量应该尽量控制在5个以内,并且单个索引的字段数不超过五个
13.选择合理的字段类型
char表示固定字符串类型,该类型存储字段长度固定,会浪费存储空间;varchar表示变长字符串类型,会根据实际数据的长度调整,不会浪费存储空间
因此在选择字段类型时,需要注意以下:
能用数字类型就不用字符串,字符的处理往往比数字要慢;
尽可能使用小的类型,比如:用bit存储布尔值,用tinyint存枚举值;
长度固定的字符串类型,用char类型;
长度可变的字符串类型,用varchar;
金额字段用decimal,避免精度丢失。
14.提升group by的效率
group by的作用是去重和分组,和having一起使用表示分组后根据一定的条件过滤数据,但大部分情况下此种写法的性能不好,因此需要where条件先缩小数据的范围,就能提升sql整体性能
15.索引优化
赞25
踩0