# 1. 为三个列建立一个复合索引ALTERTABLE president ADDINDEX ad_index (country,state,city);# 建立一个复合索引,其实就是为每个列进行一个同名索引# 2. 能够使用到该索引的查询 : 只与组合有关系,和组合的前后顺序无关EXPLAINSELECT*FROM president WHERE country ="中国";EXPLAINSELECT*FROM president WHERE country ="中国"AND state ="山西";EXPLAINSELECT*FROM president WHERE country ="中国"AND state ="山西"AND city ="cun";# 3. 不能使用到该索引的查询EXPLAINSELECT*FROM president WHERE state ="山西";EXPLAINSELECT*FROM president WHERE city ="cun";EXPLAINSELECT*FROM president WHERE city ="cun"AND state ="山西";
4.6 不要建立过多的索引
索引数目越多,对应的写操作就越慢,因此不能太多索引;
如上面的例子中,如果有复合索引,就不用再为country单独建立一个索引;
5. 索引失效
5.1 数据隐式类型转换
# 1. 把数值数据列和字符串常量比较时候,索引不会失效# '14' 只能转换为双精度的14,因此索引不会失效EXPLAINSELECT*FROM president WHERE num_col ="14";'14';# 2. 将字符串数据列和数值比较,索引失效# 14 可以等于的字符串包含 '14','14.0', '14th'EXPLAINSELECT*FROM president WHERE str_col =14;
5.2 like匹配时,%前置
# 1. 索引失效EXPLAINSELECT*FROM president WHERE str_col like'%4';# 1. 索引不会失效EXPLAINSELECT*FROM president WHERE str_col like'4%';
5.3 索引列使用函数或者计算
# 1.1 列计算导致索引失效: 前面的字段相当于变成了 id + 1,而不是idEXPLAINSELECT*FROM president WHERE id +1<4;# 1.2 修改sql,使其能够使用索引EXPLAINSELECT*FROM president WHERE id <3;# 2.1 索引列进行了函数化运算,索引失效EXPLAINSELECT*FROM president WHEREYEAR(created_time)<2016;# 2.2. 修改sql, 能够使用索引# 如果不加 '',引发数据类型转换,索引页会失效EXPLAINSELECT*FROM president WHERE created_time <'2016-01-01';# 3.1 索引列进行了函数化运算,索引失效EXPLAINSELECT*FROM president WHERE CONCAT(str_col,' ')='shu';
5.4 or两边的必须都为带索引
# 1. id和num_col都包含索引: 可以走索引;EXPLAINSELECT*FROM president WHERE id =1or num_col =3;# 2. first_name 不包含索引,因此整个sql都不会走索引EXPLAINSELECT*FROM president WHERE id =1or first_name ='shu';# 测试的时候要注意列数据维度,不让你可能因为这个影响or测试
5.5 组合索引
# 组合索引,索引的第二列,第三列,二,三列的AND查询,都不会走索引;
5.7 列数据维度小时
当列的数据维度较小的时候,会导致索引失效
5.8 系统默认
当全表扫描速度比索引速度快时,mysql会使用全表扫描,此时索引失效。
二、查询优化
sql在执行时,mysql会对该sql进行查询优化,会充分利用索引及其他信息;
尽可能快的排除无用行;
# 1. 查询1=2不可能成立,因此该sql不会搜索全表,而是直接返回空数据集EXPLAINSELECT*FROM cnip WHERE name ="张三"AND1=2;# 2. 多个列匹配: mysql在对列排查的时候并不会去按照sql的书写顺序# 哪个条件能够排除的数据最多,则先执行哪个,这样就不用对一些不符合的行数据# 进行反复的多个条件的校验;SELECT*FROM cnip WHERE condition1 AND condition2 And condition3;
1. 工作原理
1.1 使用EXPLAIN查看执行
通过EXPLAIN语句,查看当前是否索引正确使用,以及搜索效率如何;
-- 1. 正确使用了索引,因此只搜索一行,有效数据为100%-- 2. 删除掉该索引,全表搜索了六行,有效数据为16%EXPLAINSELECT*FROM president WHERE country ="中国";
possible_key:可能使用到的索引;
key:实际使用到的索引;
1.2 使用相同类型的数据进行比较
当多表链接的时候,两个列数据比较时候,相同类型数据的比较相比不同类型数据,效率会快很多;
相同数据类型: INT 和 INT, CHAR(20)和VARCHAR(20)/CHAR(20);
不同数据类型: INT和BIGINT,CHAR(20)和CHAR(40);
如果数据类型不同,则尽量改为相同的数据列再进行比较;
1.3 避免数据类型自动转换
在列数据匹配的时候,mysql可以自动进行数据类型转换;
类型转换伴随着一定的性能损失;
# 1. code列为INT类型,但是和'14'进行匹配时候,会将字符和数字转换为双精度数;SELECT*FROM president WHERE code ='14';
一、索引涉及查询优化,首先从索引出发,一般能最快最好的解决问题;索引解决完成后,再从其他角度出发去优化查询;1. 索引优点案例一SELECT * FROM ad WHERE company_num<14无索引全局搜索,挑选出合适行数据,若数据量大,则全表扫描耗时;带索引扫描索引,挑选出两个13的数据;当扫描到14时,因为索引已经排序,所以下面条件都不满足;退出查询,将索引为13对应的两个数据行结果返回;优化原因方式一:得知匹配行在什么地方结束,从而不用扫描其他