sql优化

1.如果只使用少量字段,尽量不要用select *

select * 会把数据库所有的字段全部查询出来,浪费内存和CPU;
如果需要查询的字段都是索引字段,则不要用select *,不会走覆盖索引。

2.使用union all 不使用union

union关键字会进行遍历、排序、去重;非常耗时,耗CPU

(select * from table_name where id=1) 
union all
(select * from table_name where id=2);

3.小表驱动大表

也就是说,如果查询需要同时满足两张表的数据,则应该先查询满足小表,将满足小表的结果集作为一个条件来查询大表。
in 和 exists 语法
如果sql语句中包含了in关键字,则它会优先执行in里面的子查询语句,然后再执行in外面的语句。如果in里面的数据量很少,作为条件查询速度更快。
而如果sql语句中包含了exists关键字,它优先执行exists左边的语句(即主查询语句)。然后把它作为条件,去跟右边的语句匹配。如果匹配上,则可以查询出数据。如果匹配不上,数据就被过滤掉了。

  • in 适用于左边大表,右边小表。
  • exists 适用于左边小表,右边大表。

4.批量操作

四个方面解释:

  • 1、从网络传输方面来说,批量插入多条数据,更省空间。
  • 2、从连接数量来说,批量插入只使用一个连接,在使用数据库连接池的情况下,逐个插入可能会占用多个连接。
  • 3、从事务方面来说,逐条插入每次都会新建一个事务,批量插入只会使用一个事务。
  • 4、从日志方面来说,由于逐条插入每次都会插入binlog事务日志,也会影响效率。

5.多用limit

如果是查询前面几条记录,可以通过limit num来实现。

6.in中的值不要太多

如果in中的值太多,可能会造成索引失效,造成接口超时。如果in 中的值确实很多,可以采用多线程去处理,分批查询出结果后再汇总

7.增量查询、高效的分页查询

如果数据量很大,分页查询时查询后面的数据,通过limit 100000,10去查询,需要查询1000010条数据,再剔除前面的数据,很浪费资源。
可以通过将上一页的最大id作为查询的一个必须条件来查询,每次查询10条记录。sql可以这样写

select * from table_name where id>#{lastId} limit 10 

8.连表查询代替子查询

因为子查询执行查询时,会创建一个临时表,查询完毕后,需要删除这些临时表,有一些额外的性能消耗。

9.join的表 不要太多

如果join太多,mysql在选择索引的时候会非常复杂,很容易选错索引。
可以通过合理设计数据库冗余字段来避免join表过多的情况。
left join和inner join

  • left join:求两个表的交集外加左表剩下的数据。
  • inner join:求两个表交集的数据。
    如果两张表使用inner join关联,mysql会自动选择两张表中的小表,去驱动大表,所以性能上不会有太大的问题。
    两张表使用left join关联,mysql会默认用left join关键字左边的表,去驱动它右边的表,所以使用时需要注意下。

10.索引

索引能够显著的提升查询sql的性能,但是也会在增、删、改时增加数据库的消耗。
建立索引时不是越多越好、应该适当合理的建立索引。详细参考https://www.jianshu.com/p/7a29cd77ec7e

11.设计数据库时 字段类型、长度设计合理

我们在选择字段类型时,应该遵循这样的原则:

  • 能用数字类型,就不用字符串,因为字符的处理往往比数字要慢。
  • 尽可能使用小的类型,比如:用bit存布尔值,用tinyint存枚举值等。
  • 长度固定的字符串字段,用char类型。
  • 长度可变的字符串字段,用varchar类型。
  • 金额字段用decimal,避免精度丢失问题。

12.提升group by效率

group by 时结果集应尽量小,应该在group by之前就通过查询条件优先过滤掉数据。既group by应该在查询条件后面
参考博客:https://zhuanlan.zhihu.com/p/431837711

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容