MySQL提高篇(五)--- SQL语句优化

优化insert语句:

  如果需要对同一张表插入多条数据,可以将多条插入语句合并为一条:

insert into tb_user values(1,'Peter');
insert into tb_user values(2,'Tom');
insert into tb_user values(3,'Jon');

  优化后:

insert into tb_user values(1,'Peter'),(2,'Tom'),(3,'Jon');
优化order by语句

  在mysql中,实际上可以认为有两种排序方式,一种是按照索引排序,另外一种是从磁盘取数据到内存再进行filesort排序。当使用explain查看sql的执行计划时,如果extra字段出现了Using filesort;即表示数据排序使用到了Filesort排序,它比按索引排序的效率低,因为按索引排序其实从磁盘中取出的数据就是有序的,不需要在内存中做额外的排序操作
  了解了这个知识之后,我们就知道为什么要让order by字段和where条件中使用同样的索引了,只要order by的顺序与索引顺序相同,mysql就不需要另外在内存中做额外的排序操作。

优化Filesort

 两次扫描算法:
  Mysql4.1之前,是使用这种方式排序,它首先根据条件取出排序字段和对应的行指针信息,然后在sort buffer中排序,如果sort buffer大小不够,则在临时表中存储排序结果,完成排序后,再根据行指针回表读取记录,因此该操作会导致大量的随机IO操作。

 一次扫描算法:
  这种方式是一次性取出所有要查询字段,然后在排序区sort buffer中排序后输出结果集,它的内存开销比较大。

  Mysql通过比较系统变量max_length_for_sort_data的大小和查询的数据集大小进行比较,来选择使用哪种排序算法。所以我们可以适当提高sort_buffer_size和max_length_for_sort_data的大小来提高排序的效率。

优化group by语句

  由于group by 后的分组结果实际上也会进行排序,所以我们也需要在group by的字段上使用与where条件一样的索引,另外,如果结果不需要排序,可以通过 order by null 来阻止排序以提高效率。

优化嵌套查询

  由于子查询需要在内存中创建临时表来完成查询功能,所以其查询效率比对应的关联查询效率低,因此建议使用关联查询替代子查询。(注意:有时候子查询会被mysql优化器优化为关联查询)

优化 or 条件查询

  
在这里插入图片描述
查看sql的执行计划

通过查看两条语句的执行计划,可以看到,union 连接比 or 条件查询效率要高,所以我们应该尽量使用union 来代替or条件查询。

优化分页查询

  对于一般的分页查询,通过创建覆盖索引可以有效的提高查询性能。但是假如需要查询的是:

select username from t_user limit 2000000,10;

这种行偏移量较大的分页查询查询效率低下,有哪些方法可以对其进行优化呢?
方法一:
  假如表是主键自增类型的,可以将上面的sql语句转换为:

select username from t_user where id > 2000000 limit 10;

这种情况有一个条件,就是表的主键是自增的且表中的记录不会进行物理删除
方法二:
  表不满足上面的两个条件,此时的优化方式为:

select username from t_user u,(select id from t_user order by id limit 2000000,10) t where u.ud = t.id; 

即在主键上完成排序分页功能然后关联回自身进行查询。

发布了28 篇原创文章 · 获赞 4 · 访问量 1318
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章