MySQL 索引分析除了 EXPLAIN 还有什么方法?

作者 | adrninistrat0r

责编 | 夕颜

出品 | CSDN(ID:CSDNnews)

前言

对于非数据库开发人员而言,难以对MySQL源码进行分析或调试,接近一个黑盒,但MySQL提供了一些命令及系统状态变量,可对索引及其他内容进行分析。掌握这些方法后,可以尽量深入地了解MySQL的一些实现细节。

MySQL索引分析除了EXPLAIN还有什么方法

通过以下方法,可以获得MySQL索引相关的数据,便于分析与理解索引相关的问题。

2.1. 通过慢查询日志记录SQL语句执行时间

参考 https://dev.mysql.com/doc/refman/5.6/en/slow-query-log.html 。

慢查询日志中包含的SQL语句,其执行时间超过long_query_time(系统参数)秒,并且至少检查min_examined_row_limit(系统参数)行。

获取初始锁的时间不包含在执行时间中。mysqld(MySQL服务器)在SQL语句执行且释放所有锁之后,将一条语句写入慢查询日志中,因此日志顺序可能与执行顺序不同。

2.1.1. 慢查询日志的系统参数

long_query_time系统参数的最小值为0,默认值为10(秒)。将慢查询日志记录到文件时,写入的时间包括微秒部分。将慢查询日志记录到表,仅写入整数时间,微秒部分将被忽略。

默认情况下,慢查询日志是禁用的。slow_query_log系统参数可以设置慢查询日志是否启用,参数值为0或OFF表示禁用,1或ON表示启用。

slow_query_log_file系统参数用于设置日志文件名称,默认值为“[主机名]-slow.log”。MySQL服务器会在data目录中创建文件,除非通过绝对路径名指定了其他目录。

log_output系统参数用于设置通用查询日志与慢查询日志的输出位置。其值为一个或多个逗号分隔的单词组成的列表,可选值为TABLE,FILE及NONE。

  • 当指定TABLE时,表示将日志记录到名为mysql的系统数据库的general_log与slow_log表中;

  • 当指定FILE时,表示将日志记录到文件中;

  • NONE表示禁用日志。

不使用索引对行进行查找的查询,需要在启用log_queries_not_using_indexes系统变量后,才会在写入慢查询日志时被包含进去。该系统默认为关闭。

查询缓存处理的查询不会被MySQL服务器记录。

2.1.2. 慢查询日志内容格式

为了通过慢查询日志记录查询语句的准确耗时,需要将慢查询日志保存至文件,log_output系统参数需要设置为FILE。

慢查询日志文件中,每条语句生成的记录都有一行以#开头的数据,并包含以下字段(所有字段在一行中显示):

  • Query_time

语句执行时间,单位为秒;

  • Lock_time

获取锁的时间,单位为秒;

  • Rows_sent

发送给客户端的行数;

  • Rows_examined

MySQL服务器层检查的行数(不包含存储引擎内部的处理)。

慢查询日志文件中的每个语句之前都有一个SET语句,该SET语句包括一个时间戳,代表该慢查询语句的记录时间。

2.1.3. 开启慢查询日志的参数配置

为了开启慢查询日志,需要修改MySQL服务器使用的配置文件的“[mysqld]”节点对应的系统参数,修改配置文件并重启MySQL服务器程序后生效。(通过“set GLOBAL 系统变量=xxx”命令修改慢查询日志相关参数时,未生效。)

系统参数设置如下所示:

slow_query_log = 1long_query_time = 0min_examined_row_limit = 1

设置“slow_query_log = 1”,以开启慢查询日志。

设置“long_query_time = 0”,将每次的查询语句都记录至慢查询日志文件中。

设置“min_examined_row_limit = 1”,可以使explain语句不出现在慢查询日志中,因为explain语句的Rows_examined为0。

slow_query_log = 1long_query_time = 0

慢查询日志文件默认生成在安装目录的data目录中。

使用可视化数据库管理工具连接MySQL时,可能会定时发送请求,也会生成在慢查询日志文件中。

2.1.4. 慢查询日志内容示例

慢查询日志内容示例如下:

# Time: 200311 19:25:39# User@Host: test[test] @ localhost [127.0.0.1]# Thread_id: 3  Schema: testdb  QC_hit: NoQuery_time: 0.015360  Lock_time: 0.001452  Rows_sent: 5222  Rows_examined: 5222use testdb;SET timestamp=1583925939;select id,cust_info from test_table_log where cust_info='1881';

经测试,以上Query_time时间仅包含MySQL服务器执行查询操作的耗时,不包含客户端展示数据的耗时。

2.2. 获取SQL语句读取索引次数

通过以下所述的方法,可以获取SQL语句执行时,读取的索引次数及方法,但不会显示读取了哪个索引。

2.2.1. SHOW STATUS语句用法

参考 https://dev.mysql.com/doc/refman/5.6/en/show-status.html 。

SHOW STATUS语句提供服务器状态信息。该语句不需要任何特权,只要能连接到服务器即可。

SHOW STATUS语句用法如下所示:

SHOW [GLOBAL | SESSION] STATUS [LIKE 'pattern' | WHERE expr]

SHOW STATUS语句接受可选的作用域修饰符,可为GLOBAL或SESSION:

  • 当指定作用域为GLOBAL时,SHOW STATUS显示全局的状态值。全局状态变量可以表示服务器本身某些方面的状态,或者表示MySQL所有连接的汇总状态。如果某个变量没有全局值,则显示会话值;

  • 当指定作用域为SESSION时,SHOW STATUS显示当前连接的状态变量值。如果某个变量没有会话值,则显示全局值。LOCAL是SESSION的代名词;

  • 如果没有指定作用域,默认使用SESSION。

每次调用SHOW STATUS语句都会使用一个内部临时表,并增加全局Created_tmp_tables值。

SHOW STATUS语句支持LIKE子句,仅显示变量名称与指定模式匹配的行。

2.2.2. 与读取索引次数相关的服务器状态变量

参考 https://dev.mysql.com/doc/refman/5.6/en/server-status-variables.html 。

与读取索引次数相关的服务器状态变量以“HANDLER_READ”开头,如下所示:

  • Handler_read_first

索引中第一个条目的读取索引次数。如果该数值很高,则表明服务器正在执行很多全索引扫描(例如,SELECT col1 FROM foo,假设col1列存在索引);

  • Handler_read_key

基于索引键读取行的请求数(即通过索引读取行的数量)。如果该数值很高,则表明表的索引很合适查询;

  • Handler_read_last

读取索引中最后一个键的请求数。使用ORDER BY时,服务器将发出一个first-key请求(对应Handler_read_first),然后发出多个next-key(对应Handler_read_next)请求;使用ORDER BY DESC时,服务器将发出一个last-key(对应Handler_read_last)请求,然后发出多个previous-key(对应Handler_read_prev)请求;

  • Handler_read_next

按索引键顺序读取下一行的请求数。当对索引列使用范围约束进行查询,或进行索引扫描时,该数值会增加;

  • Handler_read_prev

按索引键顺序读取上一行的请求数。这种读取方法主要用于优化ORDER BY … DESC;

  • Handler_read_rnd

基于固定位置读取行的请求数。当执行很多需要对结果进行排序的查询时,该数值会很高。可能有很多查询需要MySQL扫描整个表,或者联接未正确使用索引键;

  • Handler_read_rnd_next

读取数据文件下一行的请求数(即通过全表扫描读取行的数量)。当进行大量全表扫描时,该数值会变高。通常这表明表未正确建立索引,或者编写的查询未利用索引。

2.2.3. 使用SHOW STATUS获取SQL语句读取索引次数

当需要获取当前会话的SQL语句读取索引次数,可以执行SHOW STATUS查看以“HANDLER_READ”开头的服务器状态变量(以下执行命令中的HANDLER_READ大小写不限):

SHOW STATUS LIKE 'HANDLER_READ%';

若需要使以上数值重置,可以重新连接MySQL服务器(创建新的会话),或重启MySQL服务器程序。

2.2.4. SQL语句读取索引次数示例

在以下示例中,test_table_log表的create_time字段存在单列索引,id列为主键。

执行以下语句时,需要读取索引中第一个记录,Handler_read_first值加1。

select * from test_table_log order by create_time limit 1;

执行以下语句时,需要读取索引中的最后一个记录,Handler_read_last值加1。

select * from test_table_log order by create_time desc limit 1;

执行以下语句时,需要基于索引读取行,Handler_read_key值加1。

select * from test_table_log where create_time = '2020/3/10 12:23:38' limit 1;

执行以下语句时,需要基于索引读取行,Handler_read_key值加1;并需要根据索引读取后续9行,Handler_read_next值增加9。

select * from test_table_log where create_time = '2020/3/10 12:23:38' limit 10;

执行以下语句时,共查询到4条记录需要基于索引读取行,Handler_read_key值加1;并需要根据索引读取后续行,Handler_read_next值增加4。

select * from test_table_log where id >= 'testtime1583814037num1' and id <= 'testtime1583814037num1000'

执行以下语句时,需要读取索引中第一个记录,Handler_read_first值加1;并需要根据索引读取后续9行,Handler_read_next值增加9。

select * from test_table_log order by create_time limit 10;

执行以下语句时,需要读取索引中的最后一个记录,Handler_read_last值加1;并需要根据索引读取之前的9行,Handler_read_prev值增加9。

select * from test_table_log order by create_time desc limit 10;

执行以下语句时,需要通过全表扫描读取数据文件中的行,数量为110,Handler_read_rnd_next值增加110。

select * from test_table_log limit 100,10;

执行以下语句时,需要通过全表扫描读取数据文件中的行,Handler_read_rnd_next值增加超过110;并需要对查询到的10条记录进行排序,Handler_read_rnd值增加10。

select a.* from(select * from test_table_log limit 100,10) as a order by a.create_time;

2.2.5. 查询数据库表获取SQL语句读取索引次数(不使用)

参考 https://dev.mysql.com/doc/refman/5.6/en/status-table.html 。

INFORMATION_SCHEMA.GLOBAL_STATUS与INFORMATION_SCHEMA.SESSION_STATUS表与“SHOW GLOBAL STATUS”及“SHOW SESSION STATUS”命令显示对应的信息。查询示例如下:

select * from INFORMATION_SCHEMA.SESSION_STATUSwhere VARIABLE_NAME like 'HANDLER_READ%' and VARIABLE_VALUE <> '0'order by cast(VARIABLE_VALUE as UNSIGNED INTEGER) desc;

当从上述表查询数据获取SQL语句读取索引次数时,会导致Handler_read_rnd_next变量值增大;当使用排序时,还会导致Handler_read_rnd变量值增大。因此需要获取SQL语句读取索引次数时,不通过上述数据库表查询。

2.3. 获取InnoDB缓冲池中索引页与记录数

InnoDB缓冲池中索引页与记录数,可以反映MySQL在执行SQL语句时,将指定表的索引读取到缓冲池中的索引页及记录数量。

若需要重置InnoDB缓冲池相关数据,需要重启MySQL服务器程序(未找到其他方法清空InnoDB缓冲池)。

2.3.1. INNODB_BUFFER_PAGE表

参考 https://dev.mysql.com/doc/refman/5.6/en/innodb-information-schema-buffer-pool-tables.html 。

InnoDB INFORMATION_SCHEMA缓冲池表提供了缓冲池状态信息,以及有关InnoDB缓冲池页面的元数据。

InnoDB INFORMATION_SCHEMA缓冲池表中包含INNODB_BUFFER_PAGE,该表保存InnoDB缓冲池中每个页的信息。

查询INNODB_BUFFER_PAGE或INNODB_BUFFER_PAGE_LRU表可能会影响性能,应避免在生产环境查询。

2.3.2. INNODB_BUFFER_PAGE表字段

参考 https://dev.mysql.com/doc/refman/5.6/en/innodb-buffer-page-table.html 。

INNODB_BUFFER_PAGE表中包含以下关注的字段:

  • POOL_ID

缓冲池ID。是用于区分多个缓冲池实例的标识符。

  • SPACE

表空间ID。

  • PAGE_NUMBER

页编号(page number)。

  • PAGE_TYPE

页的类型。例如“INDEX”代表B+树节点,“BLOB”代表未压缩的BLOB页等。

  • TABLE_NAME

页所属的表名。该列仅适用于PAGE_TYPE值为INDEX的页。

  • INDEX_NAME

页所属的索引名。可以是聚簇索引或二级索引的名称。该列仅适用于PAGE_TYPE值为INDEX的页。

  • NUMBER_RECORDS

页的记录的数量。

2.3.3. 从INNODB_BUFFER_PAGE表获取InnoDB缓冲池中索引页与记录数

从INNODB_BUFFER_PAGE表中可获取InnoDB缓冲池中索引页与记录数,table_name字段的形式为“`[数据库名]`.`[表名]`”。

查询的示例语句如下,page_num为指定表的指定索引在InnoDB缓冲池中的页的总数,record_num为指定表的指定索引在InnoDB缓冲池中记录的总数:

select TABLE_NAME,INDEX_NAME,count(*) as page_num,sum(NUMBER_RECORDS) as record_numfrom INFORMATION_SCHEMA.INNODB_BUFFER_PAGEwhere table_name = '`testdb`.`test_table_log`'group by TABLE_NAME,INDEX_NAMEorder by page_num desc;

查询结果如下所示:


2.4. 获取InnoDB索引页操作次数

InnoDB对索引页的操作包括读取、创建及写入等。

若需要重置上述数据,需要重启MySQL服务器程序。

2.4.1. 使用SHOW STATUS获取InnoDB索引页操作次数

参考 https://dev.mysql.com/doc/refman/5.6/en/server-status-variables.html 。

MySQL服务器状态中,包含以下与InnoDB索引页操作次数相关的状态:

  • Innodb_buffer_pool_pages_data

InnoDB缓冲池中包含数据的页数。该数量包含脏页与非脏页。

  • Innodb_pages_created

对InnoDB表操作创建的页数。

  • Innodb_pages_read

对InnoDB表操作,从InnoDB缓冲池读取的页数。

  • Innodb_pages_written

对InnoDB表操作导致被写的页数。

使用SHOW STATUS获取InnoDB索引页操作次数时,可执行以下语句:

SHOW STATUS LIKE 'Innodb_pages_%';SHOW STATUS LIKE 'Innodb_buffer_pool_pages_data';

2.4.2. 查询数据库表获取InnoDB索引页操作次数

参考 https://dev.mysql.com/doc/refman/5.6/en/innodb-buffer-pool-stats-table.html 。

INFORMATION_SCHEMA.INNODB_BUFFER_POOL_STATS表提供了许多与“SHOW ENGINE INNODB STATUS”输出相同的缓冲池信息。

上述表包含以下关注的列:

  • DATABASE_PAGES

InnoDB缓冲池中包含数据的页数。该数量包含脏页与非脏页。

与“SHOW STATUS”输出中的Innodb_buffer_pool_pages_data相同。

  • NUMBER_PAGES_READ

读取的页数。

与“SHOW STATUS”输出中的Innodb_pages_read相同。

  • NUMBER_PAGES_CREATED

创建的页数。

与“SHOW STATUS”输出中的Innodb_pages_created相同。

  • NUMBER_PAGES_WRITTEN

写入的页数。

与“SHOW STATUS”输出中的Innodb_pages_written相同。

从上述表获取InnoDB索引页操作次数示例语句如下(查询操作不会导致以上参数变化):

select DATABASE_PAGES, NUMBER_PAGES_READ, NUMBER_PAGES_CREATED, NUMBER_PAGES_WRITTEN from INFORMATION_SCHEMA.INNODB_BUFFER_POOL_STATS;

2.4.3. 使用SHOW ENGINE STATUS获取InnoDB索引页操作次数(不使用)

参考 https://dev.mysql.com/doc/refman/5.6/en/show-engine.html 。

“SHOW ENGINE”显示指定存储引擎的操作信息。执行时需要“PROCESS”权限。

“SHOW ENGINE INNODB STATUS”显示来自标准InnoDB监控器的有关InnoDB存储引擎状态的大量信息。

以上输出信息全部包含在Status字段中,无法进行过滤,不方便单独查看Pages read, created, written等参数。

2.5. 获取索引页分裂次数

参考 https://dev.mysql.com/doc/refman/5.6/en/index-page-merge-threshold.html ,频繁发生页分裂可能对性能产生影响。

2.5.1. INFORMATION_SCHEMA.INNODB_METRICS表

参考 https://dev.mysql.com/doc/refman/5.6/en/innodb-metrics-table.html 。

INFORMATION_SCHEMA.INNODB_METRICS表提供了InnoDB的各种性能信息。

每个监控器代表InnoDB源代码中用于收集计数器(counter)信息的位置。每个计数器可被启动、停止及重置。

默认情况下,收集的数据比较少。为了启动、停止及重置计算器,需要对系统变量innodb_monitor_enable、innodb_monitor_disable、innodb_monitor_reset或innodb_monitor_reset_all进行设置。

INFORMATION_SCHEMA.INNODB_METRICS表包含以下关注的列:

  • NAME

计数器的唯一名称;

  • COUNT

计数器启用后的计数值;

  • STATUS

enabled代表计数器在执行,disabled代表已停止;

  • COMMENT

计数器描述。

在查询INFORMATION_SCHEMA.INNODB_METRICS表时,需要有PROCESS权限。

在INFORMATION_SCHEMA.INNODB_METRICS表中,存在NAME为“index_page_splits”,COMMENT为“Number of index page splits”的记录,即索引页分裂次数对应的计数器,COUNT列为索引页分裂次数。

select count from INFORMATION_SCHEMA.INNODB_METRICS where name='index_page_splits';

2.5.2. 启用索引页分裂次数计数器

参考 https://dev.mysql.com/doc/refman/5.6/en/innodb-information-schema-metrics-table.html 。

全局变量innodb_monitor_enable、innodb_monitor_disable可分别用于启用、禁用记数器。命令如下所示:

SET GLOBAL innodb_monitor_enable = index_page_splits;
SET GLOBAL innodb_monitor_disable = index_page_splits;

innodb_monitor_enable变量还可以MySQL配置文件的[mysqld]节点进行配置,可使用半角逗号对多项进行分隔。innodb_monitor_disable不支持在MySQL配置文件配置。

经验证,对以上系统变量进行设置时,需要有SUPER权限(root用户)。

2.6. 获取执行计划

参考 https://dev.mysql.com/doc/refman/5.6/en/explain-output.html 。

EXPLAIN语句提供有关MySQL如何执行语句的信息。EXPLAIN适用于SELECT,DELETE,INSERT,REPLACE和UPDATE语句。

EXPLAIN为SELECT语句中使用的每个表返回一行信息。输出中的表的顺序,与MySQL在处理语句时读取表的顺序一致。

2.6.1. EXPLAIN输出列

EXPLAIN输出的列及含义如下所示:

2.6.2. id

id列为SELECT的标识符,其值为查询中SELECT的顺序号。

即id列反映了SELECT在执行时的顺序(从小到大)。

2.6.3. select_type

select_type列为SELECT的类型,select_type值及含义如下所示:

DEPENDENT通常表示使用了相关子查询(correlated subquery)。


2.6.4. type

type列为连接类型,描述了表的连接方式。不同的连接类型如下所示:

  • system

表只有一行(系统表)。system是const连接类型的特例。

  • const

查询的开头读取的表,最多只有一行匹配。因为只有一行,优化器的其余部分可以将此行中对应列的值视为常量。

const连接类型对应的表查询非常快,因为它们只读取一次。

将主键或唯一索引的所有部分与常量值进行比较时会使用const连接类型。

在以下示例中,tbl_name表可以作为const连接类型使用:

SELECT * FROM tbl_name WHERE primary_key=1;
SELECT * FROM tbl_name WHERE primary_key_part1=1 AND primary_key_part2=2;
  • eq_ref

对于先前的表的每种行组合,从eq_ref连接类型对应的表中读取一行。除了system和const连接类型外,eq_ref是最好的联接类型。当连接使用索引的所有部分并且索引是主键或非空唯一索引时,将使用eq_ref连接类型。

eq_ref可用于使用=运算符进行比较的索引列。比较值可以是常量,也可以是使用在此表之前读取的表中列的表达式。

在以下示例中,MySQL可以使用eq_ref连接类型处理ref_table表:

SELECT * FROM ref_table,other_table WHERE ref_table.key_column=other_table.column;
SELECT * FROM ref_table,other_table WHERE ref_table.key_column_part1=other_table.column AND ref_table.key_column_part2=1;
  • ref

对于先前的表的每种行组合,从ref连接类型对应的表读取所有具有匹配索引值的行。

如果连接仅使用索引键的最左前缀或者索引键不是主键或唯一索引(即连接不能基于索引键值选择单行),则使用ref连接类型。

如果使用的键只匹配少量几行,则ref是一个好的连接类型。

ref连接类型可用于使用=或<=>运算符进行比较的索引列。

在以下示例中,MySQL可以使用ref连接类型处理ref_table表:

SELECT * FROM ref_table WHERE key_column=expr;
SELECT * FROM ref_table,other_table WHERE ref_table.key_column=other_table.column;
SELECT * FROM ref_table,other_table WHERE ref_table.key_column_part1=other_table.column AND ref_table.key_column_part2=1;
  • fulltext

使用全文索引执行连接。

  • ref_or_null

ref_or_null与ref类似,区别在于使用ref_or_null时,MySQL对包含NULL值的行进行了额外搜索。

ref_or_null连接类型最常用于解决子查询。

在以下示例中,MySQL可以使用ref_or_null连接类型处理ref_table表:

SELECT * FROM ref_table WHERE key_column=expr OR key_column IS NULL;
  • index_merge

index_merge连接类型表示使用了索引合并优化。在这种情况下,输出行中的key列包含使用的索引列表,key_len列包含所用索引的最长键部分列表。

  • unique_subquery

unique_subquery连接类型在某些使用IN的子查询的情况下替代eq_ref,如下所示:

value IN (SELECT primary_key FROM single_table WHERE some_expr)

unique_subquery只是一个索引查找函数,可以完全替代子查询以提高效率。

  • index_subquery

index_subquery连接类型与unique_subquery类似,它替代了IN子查询,支持子查询中的非唯一索引,如下所示:

value IN (SELECT key_column FROM single_table WHERE some_expr)
  • range

range连接类型表示仅检索给定范围内的行,使用索引选择行。

EXPLAIN输出行中的key列表示使用哪个索引。key_len列包含使用的最长的索引键部分。对于此连接类型,ref列为NULL。

使用=,<>,>,> =,<,<=,IS NULL,<=>,BETWEEN,LIKE或IN()运算符中的任何一个将索引键列与常量进行比较时,可以使用range类型。

  • index

index连接类型与ALL类型类似,区别在于index连接类型有对索引树进行扫描。有两种方式:

a. 如果查询的索引是覆盖索引,并且可满足所需表的所有数据,则仅扫描索引树。在这种情况下,Extra列显示“Using index”。仅扫描索引通常比ALL连接类型快,因为索引的大小通常小于表数据。

b. 对指定索引读取数据,进行全表扫描,以按索引顺序查找数据行。Extra列不会显示“Using index”。

当查询仅使用属于单个索引一部分的列时,MySQL可以使用此连接类型。

  • ALL

对之前的表中的每个行组合进行全表扫描。

如果当前表是第一个没有标记为const的表,这通常是不好的,并且通常在所有其他情况下非常糟糕。

通常,可以通过添加索引来避免ALL连接类型,这些索引基于常量值或先前的表的列值,启用从该表的行检索。

2.6.5. possible_keys

possible_keys列表示MySQL可以选择用于查找此表的行的索引。请注意,此列于EXPLAIN输出中显示的表的顺序完全独立。

假如possible_keys列为NULL,说明没有相关的索引。

2.6.6. key

key列表示MySQL实际决定使用的索引键。如果MySQL决定使用其中一个possible_keys索引来查找行,那么该索引将被显示在key列中。

如果key列为NULL,说明MySQL未找到更有效执行查询的索引。

要强制MySQL使用或忽略possible_keys列中列出的索引,请在查询中使用FORCE INDEX,USE INDEX或IGNORE INDEX。

2.6.7. key_len

key_len列表示MySQL决定使用的索引键的长度。根据key_len的值可以确定MySQL实际使用了联合索引的多少部分。

由于索引键的存储格式,可以为NULL的列比不允许为NULL的列的索引键长度大1。

2.6.8. ref

ref列显示了在key列中列出的,用于从表中查询行的索引,与哪些列或常量进行了比较。

如果ref列的值为func,说明使用的值是某些函数的结果。

2.6.9. rows

rows列表示MySQL认为执行查询时必须检查的行数。

对于InnoDB表,该数字是估计值,可能并不总是准确的。

2.6.10. Extra

Extra列包含MySQL如何解决查询的额外信息。以下为Extra列的部分可能的值及说明:

  • Using filesort

出现该提示说明MySQL在进行排序时需要使用filesort,未使用索引进行排序。

  • Using index

从表中检索列信息时,仅使用索引树的信息,不需要进行额外的查找以读取实际行。

当仅查询属于单个索引的部分列时,可以使用此策略。

对于具有用户定义的聚簇索引的InnoDB表,即使Extra列中没有出现“Using index”,对应的索引也可能被使用。当type列为index且key列为主键时,对应以上情况。

  • Using index condition

出现该提示说明MySQL在查询时使用了索引条件下推。

  • Using sort_union(…), Using union(…), Using intersect(…)

以上显示了对应index_merge连接类型,即使用索引合并时,索引扫描合并时使用的特定算法。

  • Using temporary

为了解决该查询,MySQL需要创建一个临时表来保存结果。如果查询包含GROUP BY和ORDER BY子句,且列出了不同的列时,通常会发生这种情况。

  • Using where

WHERE子句用于限制与下一个表匹配的行,或发送到客户端的行。假如Extra列的值不是using where,且表的连接类型为ALL或index时,则说明查询语句存在一些问题,除非是特意为了获取或检查表中所有的行。

3. InnoDB读取索引页时机

InnoDB读取索引页的时机,包括但不限于MySQL启动、执行EXPLAIN语句、执行查询/插入/更新操作等情况。

为了获取InnoDB读取索引页的次数,可参考前文,查询以“Innodb_pages_”开头的系统状态,或从INFORMATION_SCHEMA.INNODB_BUFFER_POOL_STATS表查询。


3.1. MySQL启动时读取索引页

当MySQL启动时,会读取对部分表的索引。此时还未执行任何语句,查看InnoDB读取索引页的次数大于0,查看InnoDB缓冲池中索引页与记录数大于0。

3.2. 执行EXPLAIN语句时读取索引页

在执行EXPLAIN语句时,可能会读取相关表对应的索引页,若所需的索引页数据已被读取至缓冲池中,可能不会读取。对于上述情况,可查看InnoDB读取索引页的次数,执行EXPLAIN语句后次数会增加。

3.3. 执行插入/查询/更新/删除语句时读取索引页

在执行插入/查询/更新/删除语句时,可能会读取相关表对应的索引页,若所需的索引页数据已被读取至缓冲池中,可能不会读取。

4. 参考资料

以上参考的资料如下:

https://dev.mysql.com/doc/refman/5.6/en/


推荐阅读

  • 什么?一个核同时执行两个线程?

  • 征战云时代,为什么安全是关键命题?

  • 25 张图读懂「文件系统」

  • 数据平台、大数据平台、数据中台……傻傻分不清?这次终于有人讲明白了!

  • Java 二十五载,正在 Kotlin 化!

  • 维度爆炸?Python实现数据压缩如此简单

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/516815.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

阿里云助力宁波市教育局“甬上云校”停课不停学

突如其来的新冠病毒肺炎疫情&#xff0c;让全国的师生正在经历着一个非常特殊的寒假。 疫情当下&#xff0c;教育部明确要求2020年春季延期开学&#xff0c;并且鼓励利用互联网和信息化教育资源确保学生“停课不停学”。虽然远离一线战场&#xff0c;各地教育部门和学校也迅速…

Elasticsearch7.15.2 报java.lang.NoClassDefFoundError: org/elasticsearch/client/Cancellable的解决方案

文章目录1. 现象2. 分析定位3. 解决方案1. 现象 2. 分析定位 原因&#xff1a;查看依赖项的级联关系&#xff0c;发现rest-high-level-client这个7.15.2包,的引用了6.4.3的rest-client。 3. 解决方案 直接把rest-client包的7.15.2版本的依赖项加进来就好了。 springboot集成…

全流分析取证:高级威胁哪里跑?!

网络安全的趋势和技术选择 网络空间安全涉及的安全响应&#xff0c;是指在安全事件发生后&#xff0c;通过人工或者自动化的方式&#xff0c;能采取相应的措施&#xff0c;降低安全事件带来的危害和影响&#xff1b;从启明星辰发布的近几年安全态势观察报告来看&#xff0c;安…

仅用1天,为湖北黄冈中学搭建直播课堂!

一场突如其来的新冠病毒肺炎疫情&#xff0c;让在无数在备考阶段的高三学子陷入苦恼。为了阻断疫情蔓延&#xff0c;减少人员聚集&#xff0c;教育部下发“关于2020年春季延期开学的通知”。距离高考仅剩120多天&#xff0c;虽停课&#xff0c;不能停学。 1天开通直播 助力黄冈…

疫情攻坚战“分秒必争” 宜搭免费开放疫情相关应用

云栖号案例库&#xff1a;【点击查看更多上云案例】 不知道怎么上云&#xff1f;看云栖号案例库&#xff0c;了解不同行业不同发展阶段的上云方案&#xff0c;助力你上云决策&#xff01; 抗击疫情如救水火&#xff0c;必须与时间赛跑&#xff01;1月29日&#xff0c;浙江省卫生…

万师傅使用云产品,上手简单、开箱即用、省去运维烦恼

云栖号案例库&#xff1a;【点击查看更多上云案例】 不知道怎么上云&#xff1f;看云栖号案例库&#xff0c;了解不同行业不同发展阶段的上云方案&#xff0c;助力你上云决策&#xff01; 整体架构 每当我在思考技术选型方案的时候&#xff0c;翻翻阿里云的官网&#xff0c;总…

《2019~2020网络安全态势观察报告》重磅发布!

【导读】过去一年多&#xff0c;各种 APT 攻击事件、勒索挖矿事件&#xff0c;数据泄露事件&#xff0c;漏洞攻击事件仍然不绝于耳。从 ATT&CK 模型框架的兴起到实战化攻防环境的建立&#xff0c;从反序列化漏洞的攻防博弈到 VPN 漏洞的异军突起&#xff0c;从不断“APT”化…

Canal 1.1.5 启动报错:caching_sha2_password Auth failed

文章目录1. 现象2. 分析定位3. 解决方案效果图1. 现象 java.io.IOException: caching_sha2_password Auth failedat com.alibaba.otter.canal.parse.driver.mysql.MysqlConnector.negotiate(MysqlConnector.java:260) ~[canal.parse.driver-1.1.5.jar:na]at com.alibaba.otter.…

MaxCompute2.0 助力众安保险快速成长

摘要&#xff1a;2017云栖大会阿里云大数据计算服务&#xff08;MaxCompute&#xff09;专场&#xff0c;众安保险数据总监王超群带来MaxCompute助力众安保险方面的演讲。本文主要从MaxCompute优势开始谈起&#xff0c;进而谈及大数据能够为公司运营带来的好处&#xff0c;最后…

Elasticsearch7.15.2 mysql8.0.26 logstash-input-jdbc 数据全量索引构建

文章目录一、基础软件安装1. 安装mysql2. Elasticsearch7.15.2 安装部署3. kibana 安装部署4. logstash-input-jdbc 安装部署二、数据库准备2.1. 创建数据库2.2. 表结构初始化2.3. 数据初始化三、logstash 配置mysql3.1. 创建目录3.2. 上传mysql驱动3.3. 创建jdbc.conf3.4. 创建…

优酷背后的大数据秘密:资源弹性,可支撑EB级存储

在本文中优酷数据中台的数据技术专家门德亮分享了优酷从Hadoop迁移到阿里云MaxCompute后对业务及平台的价值。 本文内容根据演讲视频以及PPT整理而成。 大家好&#xff0c;我是门德亮&#xff0c;现在在优酷数据中台做数据相关的事情。很荣幸&#xff0c;我正好见证了优酷从没…

Python 本身真的有用吗?CSDN要对Python下手了!

Python 作为一种解释型技术脚本语言&#xff0c;越来越被认可为程序员新时代的风口语言。 无论是刚入门的程序员&#xff0c;还是年薪百万的 BATJ 的技术大牛都无可否认&#xff1a;Python的应用能力是成为一名码农大神的必要项。 而作为Python初学者来讲&#xff0c;最大的问题…

揭秘高德地图如何利用MaxCompute管理海量数据

摘要&#xff1a;随着自媒体的发展&#xff0c;传统媒体面临着巨大的压力和挑战&#xff0c;新华智云运用大数据和人工智能技术&#xff0c;致力于为媒体行业赋能。通过媒体大数据开放平台&#xff0c;将媒体行业全网数据汇总起来&#xff0c;借助平台数据处理能力和算法能力&a…

Elasticsearch7.15.2 mysql8.0.26 logstash-input-jdbc 数据增量索引构建

文章目录一、基础软件安装1. 安装mysql2. Elasticsearch7.15.2 安装部署3. kibana 安装部署4. logstash-input-jdbc 安装部署二、数据库准备2.1. 创建数据库2.2. 表结构初始化2.3. 数据初始化三、logstash 配置mysql3.1. 创建目录3.2. 上传mysql驱动3.3. 创建jdbc.conf3.4. 创建…

为什么说下一个十年的主战场在Serverless?

作者 | 不瞋&#xff0c;阿里云 Serverless 负责人"唯有超越&#xff0c;才能让我们走下去。"这是不瞋在阿里的第十年。从2010 年加入阿里云&#xff0c;不瞋参与了阿里云飞天分布式系统的研发&#xff0c;历任批量计算的架构师、表格存储&#xff08;NoSQL&#xff…

解密淘宝推荐实战,打造 “比你还懂你” 的个性化APP

如今&#xff0c;推荐系统已经成为各大电商平台的重要流量入口&#xff0c;谁才能够做到比用户更懂用户&#xff0c;谁占据了新零售时代的主动权。手机淘宝的推荐更是淘宝最大的流量入口和最大的成交渠道之一&#xff0c;其背后是最为复杂的业务形态和最复杂的场景技术&#xf…

Elasticsearch7.15.2 基础概念和基础语法

文章目录一、基础概念1. ES是什么&#xff1f;2. 名词定义3. 对应关系4. 索引5. 分词二、基础概念2.1. 索引创建2.2. 索引/文档删除2.3. 索引修改三、ES 查询3.1. 简单查询3.2. 分页查询3.3. 复杂查询四、利用analyze api搜索4.1. 索引创建4.2. 索引查询4.3. 分词结果4.4. 索引…

技术重塑未来工作方式

作者&#xff1a; Nutanix亚太及日本地区高级副总裁兼销售负责人 Matt Young 新冠肺炎被宣布为“大流行病”之后&#xff0c;几乎在一夜之间&#xff0c;业务连续性的概念发生了根本性变化。在此之前&#xff0c;业务连续性通常指的是企业在某一办公地点遭遇像洪灾等恶劣天气或…

Elasticsearch7.15.2 ik中文分词器 定制化分词器之扩展词库(本地)

背景&#xff1a; IK分词提供的两个分词器&#xff0c;并不支持一些新的词汇&#xff0c;有时候也不能满足实际业务需要&#xff0c;这时候&#xff0c;我们可以定义自定义词库来完成目标。 目标&#xff1a; 定制化中文分词器&#xff0c;使得我们的中文分词器支持扩展的词汇 …

多点在线构建Noxmobi全球化精准营销系统

摘要&#xff1a;大数据计算服务(MaxCompute&#xff0c;原名ODPS)是一种快速、完全托管的TB/PB级数据仓库解决方案。MaxCompute向用户提供了完善的数据导入方案以及多种经典的分布式计算模型&#xff0c;能够更快速的解决用户海量数据计算问题&#xff0c;有效降低企业成本&am…