暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Mysql的索引使用总结

原创 张程 2020-03-02
577

MySQL的索引类型包括:

BTREE 索引(目前还不支持函数索引,但是支持前缀索引,即对索引字段的前 N 个字符创建索引)。是InnoDB 存储引擎默认索引类型。
全文本(FULLTEXT)索引(只限于 CHAR、VARCHAR 和 TEXT列);
HASH 索引:只支持MEMORY 存储引擎。
只用于使用=或<=>操作符的等式比较。
优化器不能使用 HASH 索引来加速 ORDER BY 操作。

首先介绍一下关于索引的HINT使用:

use index(index1…)

可能采用该索引,不再考虑其他索引。
事例:

create index idx_emp_job on emp(job);
create index idx_emp_job2 on emp(job,sal);
desc SELECT * FROM emp USE INDEX (idx_emp_job,idx_emp_job2)  where job ='SALESMAN';

image.png

ignore index (index1…)

忽略考虑该索引

create index idx_emp_job on emp(job);
create index idx_emp_job2 on emp(job,sal);
desc SELECT * FROM emp ignore INDEX (idx_emp_job2)  where job ='SALESMAN';


image.png

desc SELECT * FROM emp ignore INDEX (idx_emp_job2,idx_emp_job)  where job ='SALESMAN';

image.png
可以看到,数据库不再考虑该索引的可能性。

force index (index1…)

强制采用该索引,与use index区别在于前者要考虑COST,而后者不考虑COST,强制使用。等价于ORACLE index()。

desc SELECT * FROM emp USE INDEX (idx_emp_job2)  where job <>'SALESMAN';

image.png

desc SELECT * FROM emp FORCE INDEX (idx_emp_job2)  where job <>'SALESMAN';

image.png
可以看到,数据库不再考虑成本而直接采用了对应索引访问。

总结一下:索引被使用或不被使用的例子

不被使用的情况:

前%查询

众所周知,数据库对前%查询一般情况均无法使用索引。
image.png
即使添加上强制走索引,也无法使用。
image.png
换成后%,索引可以使用。
image.png
创建前缀索引:

create index idx_emp_job3 on emp(job(4));

image.png
可以看到,前缀索引的特性也与普通索引保持一致,只是对索引列的前N个字符存储。

复合索引非前导列查询

image.png
不管是考虑还是强制使用,都不走索引。

查询列为OR且不全存在索引时

首先看一下表中现有索引
image.png
当条件列为OR关系时,但对应的列不全存在索引,则无法通过索引获得数据。复合索引也不可以。
image.png

image.png
指定采用索引也无法实现。

隐式转换

image.png
image.png

image.png
可以看到系统显示了警告,由于发生了类型转换,导致无法应用上述索引。
比如下例中也为类型不一致,但没有发生隐式转换,则可以用到索引。
image.png

被使用

索引列IS NULL

当索引列为is null查询时,可以使用索引。
间接证明Mysql索引存储空值。
image.png

索引列IS NOT NULL

desc select  * from emp  where job is not null\G
desc select  * from emp use index(idx_emp_job) where job is not null\G

image.png

image.png

可以看到默认采用is not null时,不会自动采用索引访问。

desc select  * from emp force index(idx_emp_job) where job is not null\G

image.png

可以看到,强制使用索引时,对应SQL是可以采用索引访问的。

image.png
查看相关SQL的成本可知,SQL未使用索引的原因,是由于通过索引访问的查询成本高于默认情况下的全表扫描成本,因此造成不自动采用索引访问。

查询列为OR且分别存在索引时

image.png

desc select * from emp  where job='SALESMAN' or sal='800.00'\G

image.png

可以看到,数据库采用了两个索引的MERGE连接。类似于ORACLE的AND-EQUAL用法。

最后修改时间:2020-03-12 13:19:11
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论