优化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;
即在主键上完成排序分页功能然后关联回自身进行查询。