单表多表使用索引优化

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


image.png

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


image.png

SQL 中查询字段的顺序,跟使用索引中字段的顺序,没有关系。优化器会在不影响 SQL 执行结果的前提下,给 你自动地优化。
  1. 最佳左前缀法则


    image.png

    查询字段与索引字段顺序的不同会导致,索引无法充分使用,甚至索引失效!
    原因:使用复合索引,需要遵循最佳左前缀法则,即如果索引了多列,要遵守最左前缀法则。指的是查询从索 引的最左前列开始并且不跳过索引中的列。
    结论:过滤条件要使用索引必须按照索引建立时的顺序,依次满足,一旦跳过某个字段,索引后面的字段都无法被使用。

  2. 不要在索引列上做任何计算
    不在索引列上做任何操作(计算、函数、(自动 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;


image.png

结论:等号左边无计算!

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

结论:等号右边无转换

  1. 索引列上不能有范围查询


    image.png

    建议:将可能做范围查询的字段的索引顺序放在最后

  2. 尽量使用覆盖索引
    即查询列和索引列一直,不要写 select*!


    image.png

6.使用不等于(!= 或者<>)的时候
mysql 在使用不等于(!= 或者<>)时,有时会无法使用索引会导致全表扫描。


image.png
  1. 字段的 is not null 和 is null


    image.png

    当字段允许为 Null 的条件下


    image.png

    isnotnull 用不到索引,isnull 可以用到索引。

8.like 的前后模糊匹配


image.png

前缀不能出现模糊匹配

  1. 减少使用 or


    image.png

    使用 unionall 或者 union 来替代:


    image.png
  2. 练习
    假设 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

image.png

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

image.png

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


image.png

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

2.2inner join


image.png

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


image.png

④结论:innerjoin 时,mysql 会自己帮你把小结果集的表选为驱动表。
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容