MySql优化之索引的命中判断

众所周知,数据库单表数据量大了以后,为了提高查询响应速度,需要创建索引。那如何判断一个查询是否命中了索引?如果命中了索引而查询效率没有提升的原因又是什么呢?

如何确认索引已建立?

MySql内置的infomation_schema库中存储了整个数据库的静态元信息,通过查询information_shcema.STATISTICS表中的信息可以查找到所有的索引信息,或者直接查看表的DDl语句。

如何确认命中?

类似的使用另外的一个内置数据库PERFORMANCE_SCHEMA .table_io_waits_summary_by_index_usage表查看。
实例:

1
2
3
4
5
6
7
8
9
10
11
12
13
SELECT
object_type,
object_schema,
object_name,
index_name,
count_star,
count_read,
COUNT_FETCH
FROM
PERFORMANCE_SCHEMA .table_io_waits_summary_by_index_usage t
WHERE
t.INDEX_NAME IS NOT NULL
and t.OBJECT_SCHEMA = 'web';

结果:

object_type object_schema object_name index_name count_star count_read COUNT_FETCH
TABLE web my_user login_name 4 4 4

验证过程

首先创建一个表:

1
2
3
4
5
create table `my_user`)
`id` bigint not null,
'login_name' varchar(255),
primary key 'id'
);

建立索引:

1
2
ALTER TABLE `my_user`
ADD INDEX `index_01` (`login_name`) USING BTREE ;

插入一些数据:

1
2
3
4
5
6
7
INSERT INTO my_user
VALUES
(1, 'admin1'),
(2, 'admin2'),
(3, 'admin3'),
(4, 'admin4'),
(5, 'admin5');

查看下索引情况:

object_type object_schema object_name index_name count_star count_read COUNT_FETCH
TABLE web my_user index_01 0 0 0

执行查询sql:

1
2
3
4
5
6
SELECT
*
FROM
my_user
WHERE
login_name = 'admin1';

再次查看索引情况:

object_type object_schema object_name index_name count_star count_read COUNT_FETCH
TABLE web my_user index_01 1 1 1

证明上次查询已命中索引,如果执行查询后count_值不改变,证明没有命中索引。

结论:

通过__preformance_schema__库可以明确确认索引的命中情况,尤其在多索引和多表关联查询的场景下。