mysql索引分析之一
mysql索引分析之二
mysql索引分析之二
- 1 mysql的索引类型
- 2 Explain执行计划
- 2.1 执行计划之 id 属性
- 2.1.1 id 的属性相同表示加载表的顺序是从上到下
- 2.1.2 id 值越大,优先级越高
- 2.1.3 id 有相同,也有不同,同时存在
- 2.2 执行计划之 select_type
- 2.2.1 Simple
- 2.2.2 Primary
- 2.2.3 DEPENDENT SUBQUERY
- 2.2.4 SUBQUERY
- 2.3 执行计划之 possible keys
- 2.4 执行计划之 key
- 2.5 执行计划之 key_len
- 2.6 执行计划之 type
- 4 索引失效的七种情形
- 4.1 组合索引最左原则
- 4.2 最左前缀模糊查询
- 4.3 数据类型不一致
- 4.4 使用函数
- 4.5 为null的查询
- 4.6 使用算术运算
- 4.7 全表扫描更快时
数据库中表和数据一一Oracle数据库scott数据库
1 mysql的索引类型
- InnoDB 主键使用的是聚簇索引
- MyISAM 所有的索引都是非聚簇索引
2 Explain执行计划
通过 explain 查看SQL执行的效率。通过 explain 可以查看如下信息:
1)查看表的加载顺序。
2)查看 sql 的查询类型。
3)哪些索引可能被使用,哪些索引实际使用了。
4)表之间的引用关系。
5)一个表中有多少行被优化器查询。
6)其他一些额外的辅助信息。
2.1 执行计划之 id 属性
ld 属性是 mysgl 对查询语句中提供查询序号。用于表示本次查询过程中加载表的顺序或则查询子句执行顺序
ld 届性有二种情况
id 相同表示加载表的顺序是从上到下
id 不同 id 值越大,优先级越高,越先被执行id 有相同,也有不同,同时存在。id 相同的可以认为是一组,从上往下顺序执行:在所有的组中,id 的值越大,优先级越高,越先执行。
2.1.1 id 的属性相同表示加载表的顺序是从上到下
EXPLAIN
SELECT DNAME, ENAME
FROM DEPT LEFT JOIN EMP ON DEPT.DEPTNO = EMP.DEPTNO
2.1.2 id 值越大,优先级越高
EXPLAIN
SELECT ENAME, JOB, SAL
FROM EMP
WHERE DEPTNO IN (SELECT DEPTNO FROM DEPT)
2.1.3 id 有相同,也有不同,同时存在
EXPLAIN
SELECT ENAME,DNAME
FROM EMP
JOIN (SELECT DEPTNO,DNAME FROM DEPT GROUP BY DEPTNO,DNAME) E ON EMP.DEPTNO = E.DEPTNO
2.2 执行计划之 select_type
对当前查询语句中的查询类型进行判断
2.2.1 Simple
表示当前查询语句是一个简单查询语句。不包含子查询,不包含联合查询,不包含连接查询
EXPLAIN
SELECT ENAME, JOB, SAL
FROM EMP
2.2.2 Primary
如果执行的是一个包含子查询的查询,或则是一个联合查询。Primary 指向的外部查询语句或则是联合查询中的第一个子查询语句
EXPLAIN
SELECT EMPNO,ENAME FROM EMP
UNION
SELECT DEPTNO,DNAME FROM DEPT
2.2.3 DEPENDENT SUBQUERY
表示当前查询语句是一个子查询。并且执行条件依赖与外部查询提供的条件.
EXPLAIN
SELECT E1.ENAME, E1.JOB, E1.SAL, (SELECT MAX(E2.SAL) FROM EMP E2 WHERE E2.JOB=E1.JOB)
FROM EMP E1
2.2.4 SUBQUERY
表示当前查询是一个子查询。并且这个子查询在执行时不害要得到外部查询的帮助
EXPLAIN
SELECT ENAME, JOB, SAL, (SELECT COUNT(*) FROM DEPT) CNT
FROM EMP
2.3 执行计划之 possible keys
表示当前查询语句执行时可能用到的索引有哪些,在possible keys 可能出现多个索引,但是这些索引未必在本次查询使用到
2.4 执行计划之 key
表示当前查询语句真实使用的索引名称.如果这个字段为 null.则有两中可能.一个是当前表中没有索引。二是当前表有索引但是失效了.
2.5 执行计划之 key_len
如果本次查询使用了索引。则 key len 内容不为空
表示当前索引字段存储内突最大长度。这个长度不是精准值。只是 MysQL 估计的值。这个值越大越精准。在能得到相同结果时,这个值越小那么查询速度越快
2.6 执行计划之 type
Type 属性描述 MysQL 对本次查询的评价.是执行计划中的一个重
要属性。查询语句执行效率从高到底的顺序依次是.
NUILL:无需访问表或者索引,比如获取一个索引列的最大值或最小值。
system/const: 当查询最多匹配一行时,常出现于 where 条件是=的情况。system 是 const 的一种特殊情况,既表本身只有一行数据的情况。
eq ref: 关联查询时,根据唯一非空索引进行查询的情况。
ref: 查询时,根据非唯一非空索引进行查询的情况
range: 在一个索引上进行范围查找。
index: 遍历索引树查询,通常发生在查询结果只包含索引字段时
ALL:全表扫描,没有任何索引可以使用时。这是最差的情况,应该避免。
4 索引失效的七种情形
4.1 组合索引最左原则
在复合索引查询中,如果不是按照索引的最左列开始查找,则无法使用索引。
4.2 最左前缀模糊查询
like的模糊查询以%开头,索引失效。
SELECT * FROM t_student WHERE name LIKE '%太白';
4.3 数据类型不一致
如数据库表字段类型为varchar,where条件用number,索引会失效。
SELECT * FROM t_student WHERE idcard = 410181200009065029;
# 数据库中idcard为varchar类型导致索引失效。
4.4 使用函数
对索引的字段使用内部函数,索引也会失效。此情况下应该建立基于函数的索引。
SELECT * FROM t_student
WHERE DATE_FORMAT(create_time,'%Y-%m-%d') = '2022-06-02';
# create_time字段设置索引,那就无法使用函数,否则索引失效。
4.5 为null的查询
索引不存储null值,如果不限制索引列是not null,数据库会认为索引列有可能存在空值,所以不会按照索引进行计算。比如:
# 不走索引。
SELECT * FROM t_student WHERE address IS NULL;
# 走索引。
SELECT * FROM t_student WHERE address IS NOT NULL;
建议大家这设计字段的时候,如果没有必要的要求必须为NULL,那么最好给个默认值空字符串,这可以解决很多后续的麻烦(切记)。
4.6 使用算术运算
对索引列进行(+,-,*,/,!, !=, <>
)等运算,会导致索引失效。
SELECT * FROM user WHERE age - 1 = 20;
4.7 全表扫描更快时
如果数据库预计使用全表扫描要比使用索引快,则不使用索引。