### 8.2.3 优化信息\_SCHEMA 查询

[](<>)[](<>)

监控数据库的应用程序可能会频繁使用`INFORMATION_SCHEMA`表。要最有效地为这些表编写查询，请使用以下一般准则：

-   尝试仅查询`INFORMATION_SCHEMA`作为数据字典表的视图的表。

-   尝试仅查询静态元数据。为动态元数据选择列或使用检索条件以及静态元数据会增加处理动态元数据的开销。

笔记

数据库和表名的比较行为`INFORMATION_SCHEMA`查询可能与您的预期不同。有关详细信息，请参阅[第 10.8.7 节，“在 INFORMATION 中使用排序规则\_SCHEMA 搜索”](charset-collation-information-schema.html).

这些`INFORMATION_SCHEMA`表被实现为数据字典表的视图，因此对它们的查询从数据字典中检索信息：

```
CHARACTER_SETS
CHECK_CONSTRAINTS
COLLATIONS
COLLATION_CHARACTER_SET_APPLICABILITY
COLUMNS
EVENTS
FILES
INNODB_COLUMNS
INNODB_DATAFILES
INNODB_FIELDS
INNODB_FOREIGN
INNODB_FOREIGN_COLS
INNODB_INDEXES
INNODB_TABLES
INNODB_TABLESPACES
INNODB_TABLESPACES_BRIEF
INNODB_TABLESTATS
KEY_COLUMN_USAGE
PARAMETERS
PARTITIONS
REFERENTIAL_CONSTRAINTS
RESOURCE_GROUPS
ROUTINES
SCHEMATA
STATISTICS
TABLES
TABLE_CONSTRAINTS
TRIGGERS
VIEWS
VIEW_ROUTINE_USAGE
VIEW_TABLE_USAGE
```

某些类型的值，即使对于非视图`INFORMATION_SCHEMA`表，通过从数据字典中查找来检索。这包括数据库和表名、表类型和存储引擎等值。

一些`INFORMATION_SCHEMA`表包含提供表统计信息的列：

```
STATISTICS.CARDINALITY
TABLES.AUTO_INCREMENT
TABLES.AVG_ROW_LENGTH
TABLES.CHECKSUM
TABLES.CHECK_TIME
TABLES.CREATE_TIME
TABLES.DATA_FREE
TABLES.DATA_LENGTH
TABLES.INDEX_LENGTH
TABLES.MAX_DATA_LENGTH
TABLES.TABLE_ROWS
TABLES.UPDATE_TIME
```

这些列代表动态表元数据；也就是说，随着表格内容的变化而变化的信息。

默认情况下，MySQL 从`mysql.index_stats`和`mysql.table_stats`查询列时的字典表，这比直接从存储引擎检索统计信息更有效。如果缓存的统计信息不可用或已过期，MySQL 会从存储引擎中检索最新的统计信息并将它们缓存在`mysql.index_stats`和`mysql.table_stats`字典表。后续查询检索缓存的统计信息，直到缓存的统计信息过期。

这[`information_schema_stats_expiry`](server-system-variables.html#sysvar_information_schema_stats_expiry)session 变量定义缓存统计信息过期之前的时间段。默认值为 86400 秒（24 小时），但时间段可延长至一年。

要随时更新给定表的缓存值，请使用[`分析表`](analyze-table.html).

查询统计信息列不会存储或更新统计信息`mysql.index_stats`和`mysql.table_stats`在这些情况下的字典表：

-   当缓存的统计信息没有过期时。

-   什么时候[`information_schema_stats_expiry`](server-system-variables.html#sysvar_information_schema_stats_expiry)设置为 0。

-   当服务器启动时[`只读`](server-system-variables.html#sysvar_read_only),[`super_read_only`](server-system-variables.html#sysvar_super_read_only),[`transaction_read_only`](server-system-variables.html#sysvar_transaction_read_only)， 要么[`innodb_read_only`](innodb-parameters.html#sysvar_innodb_read_only)模式。

-   当查询还获取性能模式数据时。

[`information_schema_stats_expiry`](server-system-variables.html#sysvar_information_schema_stats_expiry)是一个会话变量，每个客户端会话都可以定义自己的过期值。从存储引擎检索并由一个会话缓存的统计信息可用于其他会话。

笔记

如果[`innodb_read_only`](innodb-parameters.html#sysvar_innodb_read_only)系统变量已启用，[`分析表`](analyze-table.html)可能会失败，因为它无法更新数据字典中的统计表，这些表使用`InnoDB`.为了[`分析表`](analyze-table.html)更新密钥分布的操作，即使该操作更新了表本身（例如，如果它是`MyISAM`桌子）。要获取更新的分布统计信息，请设置[`information_schema_stats_expiry=0`](server-system-variables.html#sysvar_information_schema_stats_expiry).

为了`INFORMATION_SCHEMA`作为数据字典表的视图实现的表，底层数据字典表上的索引允许优化器构建有效的查询执行计划。要查看优化器所做的选择，请使用[`解释`](explain.html).还可以查看服务器用于执行的查询`INFORMATION_SCHEMA`查询，使用[`显示警告`](show-warnings.html)紧随其后[`解释`](explain.html).

考虑这个语句，它标识了排序规则`utf8mb4`字符集：

```
mysql> SELECT COLLATION_NAME
       FROM INFORMATION_SCHEMA.COLLATION_CHARACTER_SET_APPLICABILITY
       WHERE CHARACTER_SET_NAME = 'utf8mb4';
+----------------------------+
| COLLATION_NAME             |
+----------------------------+
| utf8mb4_general_ci         |
| utf8mb4_bin                |
| utf8mb4_unicode_ci         |
| utf8mb4_icelandic_ci       |
| utf8mb4_latvian_ci         |
| utf8mb4_romanian_ci        |
| utf8mb4_slovenian_ci       |
...
```

服务器如何处理该语句？要找出答案，请使用[`解释`](explain.html)：

```
mysql> EXPLAIN SELECT COLLATION_NAME
       FROM INFORMATION_SCHEMA.COLLATION_CHARACTER_SET_APPLICABILITY
       WHERE CHARACTER_SET_NAME = 'utf8mb4'\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: cs
   partitions: NULL
         type: const
possible_keys: PRIMARY,name
          key: name
      key_len: 194
          ref: const
         rows: 1
     filtered: 100.00
        Extra: Using index
*************************** 2. row ***************************
           id: 1
  select_type: SIMPLE
        table: col
   partitions: NULL
         type: ref
possible_keys: character_set_id
          key: character_set_id
      key_len: 8
          ref: const
         rows: 68
     filtered: 100.00
        Extra: NULL
2 rows in set, 1 warning (0.01 sec)
```

要查看用于统计该语句的查询，请使用[`显示警告`](show-warnings.html)：

```
mysql> SHOW WARNINGS\G
*************************** 1. row ***************************
  Level: Note
   Code: 1003
Message: /* select#1 */ select `mysql`.`col`.`name` AS `COLLATION_NAME`
         from `mysql`.`character_sets` `cs`
         join `mysql`.`collations` `col`
         where ((`mysql`.`col`.`character_set_id` = '45')
         and ('utf8mb4' = 'utf8mb4'))
```

如所示[`显示警告`](show-warnings.html)，服务器处理查询[`COLLATION_CHARACTER_SET_APPLICABILITY`](information-schema-collation-character-set-applicability-table.html)作为对`字符集`和`校对`数据字典表中`mysql`系统数据库。
