Spec-Zone.ru › MySQL 5.7

8.2.3 Оптимизация запросов к INFORMATION_SCHEMA

Приложения, которые отслеживают базы данных, могут часто обращаться к таблицам INFORMATION_SCHEMA. Определенные типы запросов к таблицам INFORMATION_SCHEMA могут быть оптимизированы для более быстрого выполнения. Цель состоит в минимизации операций с файлами (например, сканирования каталога или открытия файла таблицы) для сбора информации, которая составляет эти динамические таблицы.

Примечание

Поведение сравнения имён баз данных и таблиц в запросах к INFORMATION_SCHEMA может отличаться от ожидаемого. Подробности см. в разделе 10.8.7 «Использование сортировки в запросах к INFORMATION_SCHEMA».

1) Попытка использовать постоянные значения поиска для имён баз данных и таблиц в предложении WHERE

Вы можете использовать этот принцип следующим образом:

  • Для поиска баз данных или таблиц используйте выражения, которые вычисляются в константу, такие как литеральные значения, функции, возвращающие константу, или скалярные подзапросы.

  • Избегайте запросов, использующих неконстантное значение поиска имени базы данных (или отсутствие значения поиска), поскольку они требуют сканирования каталога данных для поиска совпадающих имён каталогов баз данных.

  • Внутри базы данных избегайте запросов, использующих неконстантное значение поиска имени таблицы (или отсутствие значения поиска), поскольку они требуют сканирования каталога базы данных для поиска совпадающих файлов таблиц.

Этот принцип применим к таблицам INFORMATION_SCHEMA, показанным в следующей таблице, которая показывает столбцы, для которых постоянное значение поиска позволяет серверу избежать сканирования каталога. Например, если вы выбираете из TABLES, использование постоянного значения поиска для TABLE_SCHEMA в предложении WHERE позволяет избежать сканирования каталога данных.

Таблица Столбец для избежания сканирования каталога данных Столбец для избежания сканирования каталога базы данных
COLUMNS TABLE_SCHEMA TABLE_NAME
KEY_COLUMN_USAGE TABLE_SCHEMA TABLE_NAME
PARTITIONS TABLE_SCHEMA TABLE_NAME
REFERENTIAL_CONSTRAINTS CONSTRAINT_SCHEMA TABLE_NAME
STATISTICS TABLE_SCHEMA TABLE_NAME
TABLES TABLE_SCHEMA TABLE_NAME
TABLE_CONSTRAINTS TABLE_SCHEMA TABLE_NAME
TRIGGERS EVENT_OBJECT_SCHEMA EVENT_OBJECT_TABLE
VIEWS TABLE_SCHEMA TABLE_NAME

Преимущество запроса, ограниченного определённым именем базы данных, заключается в том, что проверка должна проводиться только для указанного каталога базы данных. Пример:

SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'test';

Использование литерального имени базы данных test позволяет серверу проверять только каталог базы данных test, независимо от количества баз данных. В противоположность этому, следующий запрос менее эффективен, поскольку он требует сканирования каталога данных для определения имён баз данных, соответствующих шаблону 'test%':

SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA LIKE 'test%';

Для запроса, ограниченного определённым именем таблицы, проверка должна проводиться только для указанной таблицы в соответствующем каталоге базы данных. Пример:

SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'test' AND TABLE_NAME = 't1';

Использование литерального имени таблицы t1 позволяет серверу проверять только файлы для таблицы t1, независимо от количества таблиц в базе данных test. В противоположность этому, следующий запрос требует сканирования каталога базы данных test для определения имён таблиц, соответствующих шаблону 't%':

SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'test' AND TABLE_NAME LIKE 't%';

Следующий запрос требует сканирования каталога базы данных для определения соответствующих имён баз данных для шаблона 'test%' и для каждой соответствующей базы данных – сканирования каталога базы данных для определения соответствующих имён таблиц для шаблона 't%':

SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'test%' AND TABLE_NAME LIKE 't%';

2) Составление запросов, минимизирующих количество открываемых файлов таблиц

Для запросов, которые ссылаются на определённые столбцы таблиц INFORMATION_SCHEMA, доступно несколько оптимизаций, которые минимизируют количество открываемых файлов таблиц. Пример:

SELECT TABLE_NAME, ENGINE FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'test';

В этом случае, после того как сервер отсканировал каталог базы данных для определения имён таблиц в базе данных, эти имена становятся доступными без дополнительных поисков в файловой системе. Таким образом, TABLE_NAME не требует открытия файлов. Значение ENGINE (движок хранения) можно определить, открыв файл .frm таблицы, не затрагивая другие файлы таблиц, такие как .MYD или .MYI файл.

Некоторые значения, такие как INDEX_LENGTH для таблиц MyISAM, требуют открытия файла .MYD или .MYI также.

Типы оптимизации открытия файлов обозначаются следующим образом:

  • SKIP_OPEN_TABLE: Файлы таблиц не нужно открывать. Информация уже стала доступна в запросе путем сканирования каталога базы данных.

  • OPEN_FRM_ONLY: Необходимо открыть только файл .frm таблицы.

  • OPEN_TRIGGER_ONLY: Необходимо открыть только файл .TRG таблицы.

  • OPEN_FULL_TABLE: Поиск информации без оптимизации. Файлы .frm, .MYD и .MYI должны быть открыты.

Следующий список показывает, как указанные выше типы оптимизации применяются к столбцам таблиц INFORMATION_SCHEMA. Для таблиц и столбцов, не имеющих имени, ни одна из оптимизаций не применяется.

  • COLUMNS: OPEN_FRM_ONLY относится ко всем столбцам

  • KEY_COLUMN_USAGE: OPEN_FULL_TABLE относится ко всем столбцам

  • PARTITIONS: OPEN_FULL_TABLE относится ко всем столбцам

  • REFERENTIAL_CONSTRAINTS: OPEN_FULL_TABLE относится ко всем столбцам

  • STATISTICS:

    Столбец Тип оптимизации
    TABLE_CATALOG OPEN_FRM_ONLY
    TABLE_SCHEMA OPEN_FRM_ONLY
    TABLE_NAME OPEN_FRM_ONLY
    NON_UNIQUE OPEN_FRM_ONLY
    INDEX_SCHEMA OPEN_FRM_ONLY
    INDEX_NAME OPEN_FRM_ONLY
    SEQ_IN_INDEX OPEN_FRM_ONLY
    COLUMN_NAME OPEN_FRM_ONLY
    COLLATION OPEN_FRM_ONLY
    CARDINALITY OPEN_FULL_TABLE
    SUB_PART OPEN_FRM_ONLY
    PACKED OPEN_FRM_ONLY
    NULLABLE OPEN_FRM_ONLY
    INDEX_TYPE OPEN_FULL_TABLE
    COMMENT OPEN_FRM_ONLY
  • TABLES:

    Столбец Тип оптимизации
    TABLE_CATALOG SKIP_OPEN_TABLE
    TABLE_SCHEMA SKIP_OPEN_TABLE
    TABLE_NAME SKIP_OPEN_TABLE
    TABLE_TYPE OPEN_FRM_ONLY
    ENGINE OPEN_FRM_ONLY
    VERSION OPEN_FRM_ONLY
    ROW_FORMAT OPEN_FULL_TABLE
    TABLE_ROWS OPEN_FULL_TABLE
    AVG_ROW_LENGTH OPEN_FULL_TABLE
    DATA_LENGTH OPEN_FULL_TABLE
    MAX_DATA_LENGTH OPEN_FULL_TABLE
    INDEX_LENGTH OPEN_FULL_TABLE
    DATA_FREE OPEN_FULL_TABLE
    AUTO_INCREMENT OPEN_FULL_TABLE
    CREATE_TIME OPEN_FULL_TABLE
    UPDATE_TIME OPEN_FULL_TABLE
    CHECK_TIME OPEN_FULL_TABLE
    TABLE_COLLATION OPEN_FRM_ONLY
    CHECKSUM OPEN_FULL_TABLE
    CREATE_OPTIONS OPEN_FRM_ONLY
    TABLE_COMMENT OPEN_FRM_ONLY
  • TABLE_CONSTRAINTS: OPEN_FULL_TABLE относится ко всем столбцам

  • TRIGGERS: OPEN_TRIGGER_ONLY относится ко всем столбцам

  • VIEWS:

    Столбец Тип оптимизации
    TABLE_CATALOG OPEN_FRM_ONLY
    TABLE_SCHEMA OPEN_FRM_ONLY
    TABLE_NAME OPEN_FRM_ONLY
    VIEW_DEFINITION OPEN_FRM_ONLY
    CHECK_OPTION OPEN_FRM_ONLY
    IS_UPDATABLE OPEN_FULL_TABLE
    DEFINER OPEN_FRM_ONLY
    SECURITY_TYPE OPEN_FRM_ONLY
    CHARACTER_SET_CLIENT OPEN_FRM_ONLY
    COLLATION_CONNECTION OPEN_FRM_ONLY

3) Используйте EXPLAIN, чтобы определить, может ли сервер использовать INFORMATION_SCHEMA оптимизации для запроса

Это особенно важно для INFORMATION_SCHEMA запросов, которые ищут информацию из нескольких баз данных, что может занять много времени и повлиять на производительность. Значение Extra в выводе EXPLAIN указывает, какие из описанных ранее оптимизаций сервер может использовать для оценки INFORMATION_SCHEMA запросов. Примеры ниже демонстрируют, какой тип информации можно ожидать в значении Extra.

mysql> EXPLAIN SELECT TABLE_NAME FROM INFORMATION_SCHEMA.VIEWS WHERE
       TABLE_SCHEMA = 'test' AND TABLE_NAME = 'v1'\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: VIEWS
         type: ALL
possible_keys: NULL
          key: TABLE_SCHEMA,TABLE_NAME
      key_len: NULL
          ref: NULL
         rows: NULL
        Extra: Using where; Open_frm_only; Scanned 0 databases

Использование постоянных значений поиска баз данных и таблиц позволяет серверу избежать сканирования каталогов. Для ссылок на VIEWS.TABLE_NAME необходимо открыть только файл .frm.

mysql> EXPLAIN SELECT TABLE_NAME, ROW_FORMAT FROM INFORMATION_SCHEMA.TABLES\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: TABLES
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: NULL
        Extra: Open_full_table; Scanned all databases

Значения поиска не предоставлены (нет WHERE-запроса), поэтому сервер должен сканировать каталог данных и каждый каталог базы данных. Для каждой таким образом определенной таблицы выбирается имя таблицы и формат строки. TABLE_NAME не требует открытия дополнительных файлов таблиц (применяется оптимизация SKIP_OPEN_TABLE). ROW_FORMAT требует открытия всех файлов таблиц (применяется OPEN_FULL_TABLE). EXPLAIN сообщает OPEN_FULL_TABLE, потому что это дороже, чем SKIP_OPEN_TABLE.

mysql> EXPLAIN SELECT TABLE_NAME, TABLE_TYPE FROM INFORMATION_SCHEMA.TABLES
       WHERE TABLE_SCHEMA = 'test'\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: TABLES
         type: ALL
possible_keys: NULL
          key: TABLE_SCHEMA
      key_len: NULL
          ref: NULL
         rows: NULL
        Extra: Using where; Open_frm_only; Scanned 1 database

Значение поиска имени таблицы не предоставлено, поэтому сервер должен просканировать каталог базы данных test. Для столбцов TABLE_NAME и TABLE_TYPE соответственно применяются оптимизации SKIP_OPEN_TABLE и OPEN_FRM_ONLY. EXPLAIN сообщает об этом, так как это дороже.

mysql> EXPLAIN SELECT B.TABLE_NAME
       FROM INFORMATION_SCHEMA.TABLES AS A, INFORMATION_SCHEMA.COLUMNS AS B
       WHERE A.TABLE_SCHEMA = 'test'
       AND A.TABLE_NAME = 't1'
       AND B.TABLE_NAME = A.TABLE_NAME\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: A
         type: ALL
possible_keys: NULL
          key: TABLE_SCHEMA,TABLE_NAME
      key_len: NULL
          ref: NULL
         rows: NULL
        Extra: Using where; Skip_open_table; Scanned 0 databases
*************************** 2. row ***************************
           id: 1
  select_type: SIMPLE
        table: B
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: NULL
        Extra: Using where; Open_frm_only; Scanned all databases;
               Using join buffer

Для первой строки вывода EXPLAIN: Постоянные значения поиска базы данных и таблиц позволяют серверу избежать сканирования каталога для значений TABLES. Ссылки на TABLES.TABLE_NAME не требуют дополнительных файлов таблиц.

Для второй строки вывода EXPLAIN: Все значения таблицы COLUMNS являются OPEN_FRM_ONLY поисками, поэтому COLUMNS.TABLE_NAME требует открытия файла .frm.

mysql> EXPLAIN SELECT * FROM INFORMATION_SCHEMA.COLLATIONS\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: COLLATIONS
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: NULL
        Extra:

В этом случае оптимизации не применяются, потому что COLLATIONS не является одной из таблиц INFORMATION_SCHEMA, для которых доступны оптимизации.

© 2025 Oracle
Licensed under the GPLv2 License.
https://docs.oracle.com/cd/E17952_01/mysql-5.7-en/information-schema-optimization.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API