1. 如何定位并优化慢查询sql?
(1)根据慢日志定位慢查询sql(将show_query_log设置为ON,超过long_query_time的sql将被记录在慢日志show_query_log_file中);
set global show_query_log = on;//将慢日志打开
set global long_query_time = 1; //设置时间为1秒
(2)使用explain等工具分析该条sql(一般将explain放在select的前面,用来描述MySQL如何执行查询操作,成功返回结果及需要执行的行数,帮助我们分析select语句从而找到效率低下的原因,让查询优化器更好地工作),要重点关注type字段(是否是index或者表示需要全表扫描的all)及extra字段(是否是表示索引查询的using index或者表示文件查询的using filesort)从而判断是否需要调优。
(3)修改sql或者尽量让sql去走索引
例:alter table person_info_large add index idx_name(name);//给name字段设置普通索引
可以使用force index()去测试各种索引,例如
select count(id) from person_info_large;//可能在MySQL的查询优化器的作用下并不是使用主键索引id去查找,而是使用了一个在其看来更有效率的唯一索引account
select count(id) from person_info_large force index(primary);//强制使用主键索引
2. 联合索引的最左前缀匹配原则及成因?
联合索引(组合索引):是指一个索引中包含多个列的索引(由多个列组成的索引)。
例如,如上图所示,假设有两个列area和title,index_area_title就表示一个由area列和title列组成的联合索引。
select * from person_info_large where area = ’ ’ and title = ’ ';//命中了联合索引index_area_title,会使用联合索引进行查找
select * from person_info_large where area = ’ ';//命中了联合索引,也可以使用联合索引进行查找
select * from person_info_large where title = ’ ';//没有命中联合索引,只能进行全表扫描
最左前缀匹配原则:
(1)最左前缀匹配原则是一种非常重要的规则,MySQL会一直向右匹配直到遇到范围查询(>,<,between,like)就停止匹配,比如"where a = 3 and b = 4 and c > 5 and d = 6"如果建立(a,b,c,d)顺序的索引,则d是用不到索引的因此不会走联合索引,而如果建立(a,b,d,c)顺序的索引,则都可以用到因此会走联合索引,而a、b、d的顺序是可以任意调整的;
(2)=和in可以乱序,比如"where a = 1 and b = 2 and c = 3"建立(a,b,c)索引的顺序可以是任意的,因为MySQL查询优化器会帮助你优化成索引可以识别的形式。
联合索引的最左前缀匹配原则的成因:
MySQL创建联合索引的规则是首先会对联合索引的最左边(也就是第一个)字段进行排序,在此基础上再对第二个字段进行排序,是一种类似于"order by 字段1,字段2"这样的一种排序规则,因此第一个字段是有序的,而第二个字段就是无序的了,所以如果直接按照第二个字段进行条件判断是用不到索引的。
3. 索引是建立的越多越好吗?
(1)数据量小的表不需要建立索引,建立索引会增加额外的开销;
(2)数据变更需要维护索引,因此更多的索引意味着更多的维护成本;
(3)更多的索引也意味着需要更多的空间。