单表
1.全值匹配
1.1 建立索引
CREATE INDEX idx_age_deptid_name ON emp(age,deptid,NAME);

结论:全职匹配指的是,查询的字段按照顺序在索引中都可以匹配到

SQL 中查询字段的顺序,跟使用索引中字段的顺序,没有关系。优化器会在不影响 SQL 执行结果的前提下,给 你自动地优化。
-
最佳左前缀法则
image.png
查询字段与索引字段顺序的不同会导致,索引无法充分使用,甚至索引失效!
原因:使用复合索引,需要遵循最佳左前缀法则,即如果索引了多列,要遵守最左前缀法则。指的是查询从索 引的最左前列开始并且不跳过索引中的列。
结论:过滤条件要使用索引必须按照索引建立时的顺序,依次满足,一旦跳过某个字段,索引后面的字段都无法被使用。 不要在索引列上做任何计算
不在索引列上做任何操作(计算、函数、(自动 or 手动)类型转换) ,会导致索引失效而转向全表扫描。
3.1 在查询列上使用了函数
EXPLAIN SELECT SQL_NO_CACHE * FROM emp WHERE age=30;
EXPLAIN SELECT SQL_NO_CACHE * FROM emp WHERE LEFT(age,3)=30;

结论:等号左边无计算!
3.2 在查询列上做了转换
create index idx_name on emp(name);
explain select sql_no_cache * from emp where name='30000';
explain select sql_no_cache * from emp where name=30000;
字符串不加单引号,则会在 name 列上做一次转换

结论:等号右边无转换
-
索引列上不能有范围查询
image.png
建议:将可能做范围查询的字段的索引顺序放在最后
-
尽量使用覆盖索引
即查询列和索引列一直,不要写 select*!
image.png
6.使用不等于(!= 或者<>)的时候
mysql 在使用不等于(!= 或者<>)时,有时会无法使用索引会导致全表扫描。

-
字段的 is not null 和 is null
image.png
当字段允许为 Null 的条件下
image.png
isnotnull 用不到索引,isnull 可以用到索引。
8.like 的前后模糊匹配

前缀不能出现模糊匹配
-
减少使用 or
image.png
使用 unionall 或者 union 来替代:
image.png 练习
假设 index(a,b,c);
Where语句 --------------------- 索引是否被使用
where a=3 -------------------Y,使用到a
where a=3 and b=5--------------Y,使用到a,b
where a=3 and b=5 and c=4----------Y,使用a,b,c
where b = 3 或者 where b = 3 and c = 4 或者 where c=4----------N
where a=3 and c=5 ---------------使用到 a, 但是 c 不可以,b 中间断了
where a=3 and b>4 and c=5 ----------使用到 a 和 b, c 不能用在范围之后,b 断了
where a is null and b is not null----------is null 支持索引 但是 is not null 不支持,所以 a 可以使用索引,但是 b 不可以使用
where a<>3-------------不能使用索引
where abs(a)=3--------不能使用 索引
where a=3 and b like 'kk%' and c=4------Y,使用到 a,b,c
where a=3 and b like '%kk' and c=4----------Y,只用到 a
where a=3 and b like '%kk%' and c=4----------Y,只用到 a
where a=3 and b like 'k%kk%' and c=4------Y,使用到 a,b,c
多表
2.1 left join

②如何优化?在哪个表上建立索引
ALTER TABLE book ADD INDEX idx_card(card);

③删除 book 表的索引:drop index idx_card on book;
在 class 表上建立索引:alter table class add index idx_card (card);

结论:
①在优化关联查询时,只有在被驱动表上建立索引才有效!
②left join 时,左侧的为驱动表,右侧为被驱动表!
2.2inner join

②两个查询字段调换顺序,发现结果也是一样的

④结论:innerjoin 时,mysql 会自己帮你把小结果集的表选为驱动表。






