1.order by优化mysql
2.group by优化算法
3.Dinstinct 优化sql
1.order by优化函数
实现方式:性能
1. 根据索引字段排序,利用索引取出的数据已是排好序的,直接返回给客户端;优化
2. 没有用到索引,将取出的数据进行一次排序操做后返回给客户端。spa
EXPLAIN SELECT m.id,m.subject,c.content FROM group_message m,group_message_content c WHERE m.group_id = 1 AND m.id = c.group_msg_id ORDER BY m.user_id\G;
optimizer对query进行了优化,它会按照m.user_id上的索引顺序来访问数据,这样获取的数据已是排好序的。指针
这种利用索引实现数据排序的方法是 MySQL 中实现结果集排序的最佳作法,利用已有的索引避免实际的排序计算所带来的资源消耗。blog
若是没有用到索引,mysql就会将取出的数据按照必定的排序算法进行排序,而后再把排好序的数据返回给客户端。mysql中主要使用两种排序算法:排序
1. 取出用于排序的条件字段和指向相应数据行的指针,在sort buffer中对条件进行排序,排好序以后利用指针取出数据行中的请求数据,而后返回给客户端;
2. 取出用于排序的条件字段和其它全部请求数据,将不用于排序的字段存放在一块内存中,而后在sort buffer中对条件字段进行排序,排好序后利用行指针将在内存中的数据进行匹配合并结果集,而后将排好序的数据返回给客户端。(减小数据的二次访问,节省了IO操做)
3.当用于排序的字段存在在多个表中,或者在排序以前要先通过join操做,mysql必须先把join的结果集放入一个临时表,以后再把临时表中的数据取到sort buffer里进行排序。
优化方式:
1. 加大max_length_for_sort_data参数的设置。当须要取出的全部数据长度小于这个参数的值的时候,mysql将采用第二重排序算法,不然,使用第一种算法,因此只要内存充足就能够设置足够大的值来让mysql采用改进的排序算法。
2. 去掉没必要要的字段。
3. 增大sort_buffer_size参数的值。当mysql对条件字段进行排序时,若是须要排序字段的总长度大于该参数的值的时候,mysql就会对须要排序的字段使用临时表进行分段,这样也会有性能的消耗。
2.group by优化
group by的实现过程除了要使用排序操做外,还要进行分组操做,若是使用到一些聚合函数,还要进行相应的聚合计算。
实现方式:
1. 使用松散(Loose)索引扫描实现group by,所谓的松散索引扫描,就是mysql不须要扫描全部知足条件的索引键便可完成group by操做
2. 使用紧凑(Tight)索引扫描实现group by,紧凑索引与松散索引最主要的区别就是在须要扫描索引的时候,紧凑索引读取全部知足条件的索引键,而后再来使用group by操做获得相应的结果。
3.当optimizer没法找到合适的索引能够利用的时候,就会选择将读取的数据放入临时表中来完成group by操做。group by操做想要利用索引,必须知足group by字段必须同时存放于同一个索引中,且该索引是一个有序索引,并且,使用不一样的聚合函数也会影响是否使用索引来实现group by操做。
优化方式:
1. 尽量利用索引而且是松散索引来完成group by操做,这的依靠调整索引或者调整query来实现;
2. 当没法利用索引的时候,必需要提供足够的sort_buffer_size来供mysql完成排序操做,以前介绍过,否则mysql会将须要排序的字段进行分段排序,会影响性能。除此以外尽可能不要对大结果集进行group by操做,由于一旦数据量超过系统最大临时表大小时,mysql会将临时表里的数据copy到磁盘上而后再进行操做,性能会成数量级的降低。
3.Dinstinct 优化
实现方式:
distinct的实现原理同group by相似,实现过程只是在group by以后只取出每一组中的第一条记录,因此distinct一样能够利用松散或者紧凑索引来实现,不一样的是,当没法利用索引实现distinct时,mysql一样会将数据取出放进一个临时表,不过不会对临时表进行排序操做。
优化方式:
尽可能使用索引,没法使用索引的时候,确保不要在大结果集上进行distinct操做,磁盘上的IO操做和内存中的IO操做性能彻底不是一个数量级的差距。