在Mysql中有一个专门负责优化select语句的优化器模块,其主要功能是通过计算分析系统中收集的各种统计信息,为客户端请求的Query给出最优的执行计划。
(1)优化更需要优化的Query
高并发低消耗的Query对整个系统的影响高于低并发高消耗的大。所以先优化高并发低消耗的Query
(2)永远用小结果集驱动大的结果集
MySQL中join(连接查询或者子查询)都是通过嵌套循环来实现的。驱动结果集越大,所需要的循环越多。驱动结果集是外层循环。
(3)尽可能在索引中完成排序
(4)仅用最有效的过滤条件(查找书中内容)
Explain展示执行计划,profiling展示cpu 内存利用率
Innodb是B-Tree索引
MyISAM有B-Tree索引和Full-Text索引
经常会有多个字段一起作为查询过滤条件存在于WHERE子句中。这时必须判断是在过滤性最好的字段上建立索引,还是在过滤条件单所有字段上建立一个组合索引。
组合索引因为有多个字段存在,理论上被更新的可能性肯定比单间索引大很多,带来的附加成本会高。但是当WHERE字句中查询条件含有多个字段时,通过多个字段组成组合索引的查询效率肯定比单建索引高很多。
多个单建索引的情况也不好。Mysql优化器大多数情况下只会选择其中一个索引,放弃其他索引。
一般应用中,只要不是其中某个过滤字段在大多数场景下能过滤90%以上的数据,而且其他过滤字段会被频繁更新,一般选择组合索引
创建索引: CREATE index group_message_author_subject on group_message(author,subject(16)) //组合索引
显示某个表的索引:show indexes FROM group_message\G
有时候Mysql系统统计信息不够完整,会造成他并没有选择一个真正最优的索引,而是选择了其他查询效率较低的索引,所以我们必须认为的强制选择使用索引。 EXPLAIN SELECT * FROM GROUP_message FORCE INDEX(idx _group_message_author_subject)WHERE user_id=3 AND author ='3' AND subject like 'weiurazs%'\G
查看sql执行时间
mysqlslap --create-schma=example --query "SELECT * FROM GROUP_message WHERE user_id=3 AND subject like 'weiurazs%' --iterations =10000
结果会显示出平均时间,最短时间,最长时间
总结:
尽量选择过滤性更好的索引
不要完全相信Mysql的Queqy Optimizer ,可以自己选择索引
如果可以不认为强制,就不要人为干预,否则不利于维护。
Mysql在更新表的Column ca的数据的同时,必须跟新Column a 的索引数据,最明显的资源消耗就是增加了更新所带来的IO量和调整索引所致的计算量。索引的存储也要占用空间,太多的索引会使存储空间资源消耗增加。
1.永远用小结果集驱动大结果集
2.优先优化内层循环,即保证join语句中被驱动表的join字段已经被索引。
尽量使用索引字段,甚至可以增加索引字段
GROUP BY的实现有三种方式
完全利用索引扫描来实现,并不需要扫描所有满足条件单索引建即完成操作。
需要满足三个条件:
1.groupby条件字段必须处在统一索引中的最前面的连续位置
2.使用group by时只能使用MAX 和MIN这连个聚合函数
3.如果引用到该索引中GROUUP BY条件之外的字段条件,它就必须以常亮存在;
当GROUP BY 条件字段并不是索引最前面的索引部分或者不是连续的,不能松散型索引扫描。但是如果Query语句中存在一个常量值来引用缺失的索引键,可以使用紧凑型索引扫描。
当GROUP BY 条件字段并不是索引最前面的索引部分或者不是连续的,不能松散型索引扫描。如果Query语句中不存在一个常量值来引用缺失的索引键,而是索引建是一个范围。那就只能用临时表实现GROUP BY
同GROUP BY