CREATETABLE staffs(
id INTPRIMARYKEYAUTO_INCREMENT,
NAME VARCHAR(24)NOTNULLDEFAULT''COMMENT'姓名',
age INTNOTNULLDEFAULT0COMMENT'年龄',
pos VARCHAR(20)NOTNULLDEFAULT''COMMENT'职位',
add_time TIMESTAMPNOTNULLDEFAULTCURRENT_TIMESTAMPCOMMENT'入职时间')CHARSET utf8 COMMENT'员工记录表';#插入数据INSERTINTO`staffs`(`name`,`age`,`pos`,`add_time`)VALUES('z3',22,'manager',NOW());INSERTINTO`staffs`(`name`,`age`,`pos`,`add_time`)VALUES('July',23,'dev',NOW());INSERTINTO`staffs`(`name`,`age`,`pos`,`add_time`)VALUES('2000',23,'dev',NOW());SELECT*FROM`staffs`;#添加索引ALTERTABLE`staffs`ADDINDEX idx_staffs_nameAgePos(`name`,`age`,`pos`);
1.全值匹配
#分析sql#索引被使用EXPLAINSELECT*FROM`staffs`WHERE`name`='july';EXPLAINSELECT*FROM`staffs`WHERE`name`='july'AND age =25;EXPLAINSELECT*FROM`staffs`WHERE`name`='july'AND age =25AND pos ='dev';#总结匹配所有索引,索引不失效
2. 最佳左前缀法则
#继续分析sql #索引失效 type ALL 全表扫描 EXPLAINSELECT*FROM`staffs`WHERE age =23AND pos ='dev';EXPLAINSELECT*FROM`staffs`WHERE pos ='dev';#总结无开头索引,也就是这里的name则索引失效————带头大哥不能死#继续分析sql #索引失效 type ALL 全表扫描 EXPLAINSELECT*FROM`staffs`WHERE`name`='july'AND pos ='dev';#总结 只用到了部分索引就是开头索引,其余索引未实现————中间兄弟不能断#最左前缀法则,查询从索引最左列开始,并且不跳过索引中间列 ——带头大哥不能死,中间兄弟不能断
#分析sql# age > 11,导致pos索引失效——范围之后全失效EXPLAINSELECT*FROM`staffs`WHERE`name`='july'AND age >11AND pos ='dev';#总结 (> < like 等操作都是使得右边的所有索引失效)
5. 尽量使用覆盖引擎,减少select *
#分析sql 按需查找最好EXPLAINSELECT*FROM`staffs`WHERE`name`='july'AND age =23AND pos ='dev';EXPLAINSELECT`name`,`age`,`pos`FROM`staffs`WHERE`name`='july'AND age =23AND pos ='dev';#直接从索引中获取值,而不用访问表EXPLAINSELECT`name`,`age`,`pos`FROM`staffs`WHERE`name`='july'AND age =23;#总结 查询自己需要的字段,尽量不要全部查询
#分析sql 全表扫描EXPLAINSELECT*FROM`staffs`WHERE`name`LIKE'%july';#继续分析sql 索引被使用,没有失效EXPLAINSELECT*FROM`staffs`WHERE`name`LIKE'july%';#解决 like '%字符串%'时的索引不被使用的方法#建表CREATETABLE tbl_user(
id INTPRIMARYKEYNOTNULLAUTO_INCREMENT,`name`VARCHAR(20)DEFAULTNULL,
age INTDEFAULTNULL,
email VARCHAR(20)DEFAULTNULL);#插入数据INSERTINTO`tbl_user`(`name`,`age`,`email`)VALUES('1aa1',21,'b@163.com');INSERTINTO`tbl_user`(`name`,`age`,`email`)VALUES('2aa2',222,'a@163.com');INSERTINTO`tbl_user`(`name`,`age`,`email`)VALUES('3aa3',265,'c@163.com');INSERTINTO`tbl_user`(`name`,`age`,`email`)VALUES('4aa4',21,'d@163.com');#分析sql 没建立索引EXPLAINSELECT*FROM`tbl_user`WHERE`name`LIKE'%aa%';EXPLAINSELECT`name`,`age`FROM`tbl_user`WHERE`name`LIKE'%aa%';EXPLAINSELECT`id`FROM`tbl_user`WHERE`name`LIKE'%aa%';EXPLAINSELECT`name`FROM`tbl_user`WHERE`name`LIKE'%aa%';EXPLAINSELECT`age`FROM`tbl_user`WHERE`name`LIKE'%aa%';#创建索引CREATEINDEX idx_user_namgAge ON`tbl_user`(`name`,`age`);#继续分析sql#type indexEXPLAINSELECT`name`,`age`FROM`tbl_user`WHERE`name`LIKE'%aa%';#type indexEXPLAINSELECT`id`FROM`tbl_user`WHERE`name`LIKE'%aa%';#type indexEXPLAINSELECT`name`FROM`tbl_user`WHERE`name`LIKE'%aa%';EXPLAINSELECT`age`FROM`tbl_user`WHERE`name`LIKE'%aa%';#type indexEXPLAINSELECT`id`,`name`FROM`tbl_user`WHERE`name`LIKE'%aa%';EXPLAINSELECT`id`,`name`,`age`FROM`tbl_user`WHERE`name`LIKE'%aa%';EXPLAINSELECT`name`,`age`FROM`tbl_user`WHERE`name`LIKE'%aa%';#type ALL 索引失效EXPLAINSELECT*FROM`tbl_user`WHERE`name`LIKE'%aa%';#type ALL 索引失效EXPLAINSELECT`id`,`name`,`age`,`email`FROM`tbl_user`WHERE`name`LIKE'%aa%';#总结 如果要查询以%开头的字段,尽量使用覆盖索引,在要查询的字段上建立索引
9. 字符串不加单引号索引失效
#分析sql 正常sql 使用了索引EXPLAINSELECT*FROM`staffs`WHERE`name`='2000';#继续分析 type ALL, 发生类型转换,索引失效EXPLAINSELECT*FROM`staffs`WHERE`name`=2000;
10. 少用or, 用它来连接时索引失效
#分析sql type ALL 索引失效EXPLAINSELECT*FROM`staffs`WHERE`name`='july'OR`name`='z3';