Spec-Zone.ru › MySQL 9.2

15.8.2 Выражение EXPLAIN

{EXPLAIN | DESCRIBE | DESC}
    tbl_name [col_name | wild]

{EXPLAIN | DESCRIBE | DESC}
    [explain_type] [INTO variable]
    {[schema_spec] explainable_stmt | FOR CONNECTION connection_id}

{EXPLAIN | DESCRIBE | DESC} ANALYZE [FORMAT = TREE] [schema_spec] select_statement

{EXPLAIN | DESCRIBE | DESC} ANALYZE FORMAT = JSON INTO variable [schema_spec] select_statement

explain_type: {
    FORMAT = format_name
}

format_name: {
    TRADITIONAL
  | JSON
  | TREE
}

explainable_stmt: {
    SELECT statement
  | TABLE statement
  | DELETE statement
  | INSERT statement
  | REPLACE statement
  | UPDATE statement
}

schema_spec:
FOR {SCHEMA | DATABASE} schema_name

Выражения DESCRIBE и EXPLAIN являются синонимами. На практике ключевое слово DESCRIBE чаще используется для получения информации о структуре таблицы, в то время как EXPLAIN используется для получения плана выполнения запроса (то есть, объяснения того, как MySQL будет выполнять запрос).

В следующем обсуждении используются ключевые слова DESCRIBE и EXPLAIN в соответствии с этими случаями использования, но парсер MySQL рассматривает их как полностью синонимичные.

  • Получение информации о структуре таблицы

  • Получение информации о плане выполнения

  • Получение информации с помощью EXPLAIN ANALYZE

Получение информации о структуре таблицы

DESCRIBE предоставляет информацию о столбцах в таблице:

mysql> DESCRIBE City;
+------------+----------+------+-----+---------+----------------+
| Field      | Type     | Null | Key | Default | Extra          |
+------------+----------+------+-----+---------+----------------+
| Id         | int(11)  | NO   | PRI | NULL    | auto_increment |
| Name       | char(35) | NO   |     |         |                |
| Country    | char(3)  | NO   | UNI |         |                |
| District   | char(20) | YES  | MUL |         |                |
| Population | int(11)  | NO   |     | 0       |                |
+------------+----------+------+-----+---------+----------------+

DESCRIBE является сокращением для SHOW COLUMNS. Эти выражения также отображают информацию для представлений. Описание для SHOW COLUMNS предоставляет дополнительную информацию об выходных столбцах. См. Раздел 15.7.7.6, «Выражение SHOW COLUMNS».

По умолчанию DESCRIBE отображает информацию обо всех столбцах в таблице. col_name, если указано, представляет имя столбца в таблице. В этом случае выражение отображает информацию только для указанного столбца. wild, если указано, представляет строку шаблона. Она может содержать символы подстановки SQL % и _. В этом случае выражение отображает выходные данные только для столбцов, имена которых соответствуют строке. Не нужно заключать строку в кавычки, если она не содержит пробелов или других специальных символов.

Выражение DESCRIBE предоставляется для совместимости с Oracle.

Выражения SHOW CREATE TABLE, SHOW TABLE STATUS и SHOW INDEX также предоставляют информацию о таблицах. См. Раздел 15.7.7, «Выражения SHOW».

Переменная системы explain_format не влияет на вывод EXPLAIN при использовании для получения информации о столбцах таблицы.

Получение информации о плане выполнения

Команда EXPLAIN предоставляет информацию о том, как MySQL выполняет запросы:

  • EXPLAIN работает с командами SELECT, DELETE, INSERT, REPLACE, UPDATE и TABLE.

  • Когда EXPLAIN используется с командой, допускающей анализ, MySQL отображает информацию из оптимизатора о плане выполнения запроса. То есть MySQL поясняет, как он обработает запрос, включая информацию о том, как таблицы соединяются и в каком порядке.

    Для получения информации о использовании EXPLAIN для получения информации о плане выполнения см. Раздел 10.8.2, «Формат вывода EXPLAIN».

  • Когда EXPLAIN используется с FOR CONNECTION connection_id вместо команды, допускающей анализ, отображается план выполнения запроса, выполняемого в указанном соединении.

    См. Раздел 10.8.4, «Получение информации о плане выполнения для указанного подключения».

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

    См. Раздел 10.8.3, «Расширенный формат вывода EXPLAIN».

  • EXPLAIN полезно для проверки запросов, включающих партиционированные таблицы.

    См. Раздел 26.3.5, «Получение информации о разбиениях».

  • Опция FORMAT может быть использована для выбора формата вывода. TRADITIONAL представляет вывод в табличном формате. Это значение по умолчанию, если нет опции FORMAT.

    Формат JSON отображает информацию в формате JSON. Формат TREE отображает информацию в виде дерева с более точными описаниями обработки запроса по сравнению с форматом TRADITIONAL; это единственный формат, который показывает использование соединения с хешированием (см. Раздел 10.2.1.4, «Оптимизация соединения с хешированием») и всегда используется для EXPLAIN ANALYZE.

    В MySQL 9.2 формат вывода по умолчанию, используемый командой EXPLAIN (то есть, когда у неё нет опции FORMAT), определяется значением системной переменной explain_format. Точное влияние этой переменной описано позже в этом разделе.

    MySQL 9.2 поддерживает дополнительную опцию INTO с EXPLAIN FORMAT=JSON, что позволяет сохранить вывод в формате JSON в переменную пользователя, например так:

    mysql> EXPLAIN FORMAT=JSON INTO @myselect
        ->     SELECT name FROM a WHERE id = 2;
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> SELECT @myselect\G
    *************************** 1. row ***************************
    @myex: {
      "query_block": {
        "select_id": 1,
        "cost_info": {
          "query_cost": "1.00"
        },
        "table": {
          "table_name": "a",
          "access_type": "const",
          "possible_keys": [
            "PRIMARY"
          ],
          "key": "PRIMARY",
          "used_key_parts": [
            "id"
          ],
          "key_length": "4",
          "ref": [
            "const"
          ],
          "rows_examined_per_scan": 1,
          "rows_produced_per_join": 1,
          "filtered": "100.00",
          "cost_info": {
            "read_cost": "0.00",
            "eval_cost": "0.10",
            "prefix_cost": "0.00",
            "data_read_per_join": "408"
          },
          "used_columns": [
            "id",
            "name"
          ]
        }
      }
    }
    1 row in set (0.00 sec)
    

    Это работает с любыми допускающими анализ запросами (SELECT, TABLE, INSERT, UPDATE, REPLACE или DELETE). Примеры использования с командами UPDATE и DELETE показаны здесь:

    mysql> EXPLAIN FORMAT=JSON INTO @myupdate
        ->   UPDATE a SET name2 = "garcia" WHERE id = 3;
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> EXPLAIN FORMAT=JSON INTO @mydelete
        ->     DELETE FROM a WHERE name1 LIKE '%e%';
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> SELECT @myupdate, @mydelete\G
    *************************** 1. row ***************************
    @myupdate: {
      "query_block": {
        "select_id": 1,
        "table": {
          "update": true,
          "table_name": "a",
          "access_type": "range",
          "possible_keys": [
            "PRIMARY"
          ],
          "key": "PRIMARY",
          "used_key_parts": [
            "id"
          ],
          "key_length": "4",
          "ref": [
            "const"
          ],
          "rows_examined_per_scan": 1,
          "filtered": "100.00",
          "attached_condition": "(`db`.`a`.`id` = 3)"
        }
      }
    }
    @mydelete: {
      "query_block": {
        "select_id": 1,
        "table": {
          "delete": true,
          "table_name": "a",
          "access_type": "ALL",
          "rows_examined_per_scan": 2,
          "filtered": "100.00",
          "attached_condition": "(`db`.`a`.`name1` like '%e%')"
        }
      }
    }
    1 row in set (0.00 sec)
    

    Вы можете работать с этим значением, используя функции MySQL JSON так же, как и с любым другим значением JSON, например, с помощью функции JSON_EXTRACT():

    mysql> SELECT JSON_EXTRACT(@myselect, "$.query_block.table.key");
    +----------------------------------------------------+
    | JSON_EXTRACT(@myselect, "$.query_block.table.key") |
    +----------------------------------------------------+
    | "PRIMARY"                                          |
    +----------------------------------------------------+
    1 row in set (0.01 sec)
    
    mysql> SELECT JSON_EXTRACT(@myupdate, "$.query_block.table.access_type") AS U_acc,
        ->        JSON_EXTRACT(@mydelete, "$.query_block.table.access_type") AS D_acc;
    +---------+-------+
    | U_acc   | D_acc |
    +---------+-------+
    | "range" | "ALL" |
    +---------+-------+
    1 row in set (0.00 sec)
    

    Для сложных запросов вывод в формате JSON может быть достаточно большим; в частности, при чтении может быть сложно сопоставить закрывающие и открывающие скобки. Чтобы заставить ключ структуры JSON, если он есть, повторяться рядом с закрывающей скобкой, задайте значение переменной end_markers_in_json=ON. Следует помнить, что это, хотя и упрощает чтение вывода, делает JSON невалидным, что приводит к ошибке при использовании функций JSON.

    См. также Раздел 14.17, «Функции JSON».

    Попытка использовать предложение INTO без явного включения FORMAT=JSON приводит к отклонению EXPLAIN с . Это верно независимо от текущего значения системной переменной explain_format.

    Предложение INTO не поддерживается с FOR CONNECTION.

    INTO также не поддерживается с EXPLAIN ANALYZE, когда explain_json_format_version=1.

    Важно

    Если по какой-либо причине анализируемый запрос отклоняется, переменная пользователя не обновляется.

  • MySQL 9.2 поддерживает предложение FOR SCHEMA, которое заставляет EXPLAIN вести себя так, как будто анализируемый запрос был выполнен в указанной базе данных. FOR DATABASE поддерживается как синоним. Простой пример использования показан здесь:

    mysql> USE b;
    Database changed
    mysql> CREATE SCHEMA s1;
    Query OK, 1 row affected (0.01 sec)
    
    mysql> CREATE SCHEMA s2;
    Query OK, 1 row affected (0.01 sec)
    
    mysql> USE s1;
    Database changed
    mysql> CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, c2 INT NOT NULL);
    Query OK, 0 rows affected (0.04 sec)
    
    mysql> USE s2;
    Database changed
    mysql> CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, c2 INT NOT NULL, KEY i1 (c2));
    Query OK, 0 rows affected (0.04 sec)
    
    mysql> USE b;
    Database changed
    mysql> EXPLAIN FORMAT=TREE FOR SCHEMA s1 SELECT * FROM t WHERE c2 > 50\G
    *************************** 1. row ***************************
    EXPLAIN: -> Filter: (t.c2 > 50)  (cost=0.35 rows=1)
        -> Table scan on t  (cost=0.35 rows=1)
    
    1 row in set (0.00 sec)
    
    mysql> EXPLAIN FORMAT=TREE FOR SCHEMA s2 SELECT * FROM t WHERE c2 > 50\G
    *************************** 1. row ***************************
    EXPLAIN: -> Filter: (t.c2 > 50)  (cost=0.35 rows=1)
        -> Covering index scan on t using i1  (cost=0.35 rows=1)
    
    1 row in set (0.00 sec)
    

    Если база данных не существует, запрос отклоняется с ошибкой. Если у пользователя нет необходимых привилегий для выполнения запроса, он отклоняется с ошибкой.

    FOR SCHEMA несовместим с FOR CONNECTION.

EXPLAIN требует тех же привилегий, что и для выполнения анализируемого запроса. Кроме того, EXPLAIN также требует привилегии SHOW VIEW для любого анализируемого представления. EXPLAIN ... FOR CONNECTION также требует привилегии PROCESS, если указанное соединение принадлежит другому пользователю.

Системная переменная explain_format определяет формат вывода из команды EXPLAIN при отображении плана выполнения запроса. Эта переменная может принимать любые значения, используемые с опцией FORMAT, с добавлением DEFAULT в качестве синонима для TRADITIONAL.

Следующий пример использует таблицу country из базы данных world, которую можно получить из MySQL: Other Downloads:

mysql> USE world; # Make world the current database
Database changed

Проверка значения explain_format показывает, что оно имеет значение по умолчанию, и что EXPLAIN (без опции FORMAT) использует традиционный табличный вывод:

mysql> SELECT @@explain_format;
+------------------+
| @@explain_format |
+------------------+
| TRADITIONAL      |
+------------------+
1 row in set (0.00 sec)

mysql> EXPLAIN SELECT Name FROM country WHERE Code Like 'A%';
+----+-------------+---------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
| id | select_type | table   | partitions | type  | possible_keys | key     | key_len | ref  | rows | filtered | Extra       |
+----+-------------+---------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | country | NULL       | range | PRIMARY       | PRIMARY | 12      | NULL |   17 |   100.00 | Using where |
+----+-------------+---------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

Если мы установим значение explain_format в TREE, а затем повторно выполним ту же команду EXPLAIN, вывод будет в формате дерева:

mysql> SET @@explain_format=TREE;
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT @@explain_format;
+------------------+
| @@explain_format |
+------------------+
| TREE             |
+------------------+
1 row in set (0.00 sec)

mysql> EXPLAIN SELECT Name FROM country WHERE Code LIKE 'A%';
+--------------------------------------------------------------------------------------------------------------+
| EXPLAIN                                                                                                      |
+--------------------------------------------------------------------------------------------------------------+
| -> Filter: (country.`Code` like 'A%')  (cost=3.67 rows=17)
    -> Index range scan on country using PRIMARY over ('A' <= Code <= 'A????????')  (cost=3.67 rows=17)  |
+--------------------------------------------------------------------------------------------------------------+
1 row in set, 1 warning (0.00 sec)

Как уже отмечалось, опция FORMAT переопределяет это значение.

Выполнение той же команды EXPLAIN, используя опцию FORMAT=JSON вместо FORMAT=TREE, демонстрирует это:

mysql> EXPLAIN FORMAT=JSON SELECT Name FROM country WHERE Code LIKE 'A%';
+------------------------------------------------------------------------------+
| EXPLAIN                                                                      |
+------------------------------------------------------------------------------+
| {
  "query_block": {
    "select_id": 1,
    "cost_info": {
      "query_cost": "3.67"
    },
    "table": {
      "table_name": "country",
      "access_type": "range",
      "possible_keys": [
        "PRIMARY"
      ],
      "key": "PRIMARY",
      "used_key_parts": [
        "Code"
      ],
      "key_length": "12",
      "rows_examined_per_scan": 17,
      "rows_produced_per_join": 17,
      "filtered": "100.00",
      "cost_info": {
        "read_cost": "1.97",
        "eval_cost": "1.70",
        "prefix_cost": "3.67",
        "data_read_per_join": "16K"
      },
      "used_columns": [
        "Code",
        "Name"
      ],
      "attached_condition": "(`world`.`country`.`Code` like 'A%')"
    }
  }
}                                                                              |
+------------------------------------------------------------------------------+
1 row in set, 1 warning (0.00 sec)

Для возврата к табличному формату вывода по умолчанию для EXPLAIN, установите explain_format в TRADITIONAL. Или можно установить её в DEFAULT, что имеет тот же эффект, как показано здесь:

mysql> SET @@explain_format=DEFAULT;
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT @@explain_format;
+------------------+
| @@explain_format |
+------------------+
| TRADITIONAL      |
+------------------+
1 row in set (0.00 sec)

MySQL 9.2 поддерживает два варианта формата вывода JSON. Версия 1 — линейный формат, всегда используемый в MySQL 8.2 и более ранних версиях; он остаётся значением по умолчанию в MySQL 9.2 и используется в примерах, уже показанных в этом разделе.

Версия 2 формата вывода JSON основана на путях доступа и предназначена для обеспечения совместимости с будущими версиями MySQL Optimizer.

Переключение на формат версии 2 можно осуществить, установив значение системной переменной сервера explain_json_format_version в 2, как показано здесь для той же команды EXPLAIN, что и в предыдущем примере:

mysql> SELECT @@explain_json_format_version;
+-------------------------------+
| @@explain_json_format_version |
+-------------------------------+
|                             1 |
+-------------------------------+
1 row in set (0.00 sec)

mysql> SET @@explain_json_format_version = 2;
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT @@explain_json_format_version;
+-------------------------------+
| @@explain_json_format_version |
+-------------------------------+
|                             2 |
+-------------------------------+
1 row in set (0.00 sec)

mysql> EXPLAIN FORMAT=JSON SELECT Name FROM country WHERE Code LIKE 'A%'\G
EXPLAIN: {
  "query": "/* select#1 */ select `world`.`country`.`Name` AS `Name` from `world`.`country` where (`world`.`country`.`Code` like 'A%')",
  "query_plan": {
    "inputs": [
      {
        "ranges": [
          "('A' <= Code <= 'A????????')"
        ],
        "covering": false,
        "operation": "Index range scan on country using PRIMARY over ('A' <= Code <= 'A????????')",
        "index_name": "PRIMARY",
        "table_name": "country",
        "access_type": "index",
        "key_columns": [
          "Code"
        ],
        "schema_name": "world",
        "used_columns": [
          "Code",
          "Name"
        ],
        "estimated_rows": 17.0,
        "index_access_type": "index_range_scan",
        "estimated_total_cost": 3.668778400708174
      }
    ],
    "condition": "(country.`Code` like 'A%')",
    "operation": "Filter: (country.`Code` like 'A%')",
    "access_type": "filter",
    "estimated_rows": 17.0,
    "filter_columns": [
      "world.country.`Code`"
    ],
    "estimated_total_cost": 3.668778400708174
  },
  "query_type": "select",
  "json_schema_version": "2.0"
}
1 row in set, 1 warning (0.01 sec)

Установление значения explain_json_format_version = 2 также включает поддержку предложения INTO с EXPLAIN ANALYZE FORMAT=JSON, что позволяет сохранить JSON-вывод в переменную пользователя, как показано здесь:

mysql> EXPLAIN ANALYZE FORMAT=JSON INTO @v1
    ->   SELECT Name FROM country WHERE Code LIKE 'A%'\G
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> SELECT @v1\G
*************************** 1. row ***************************
@v1: {
  "query": "/* select#1 */ select `world`.`country`.`Name` AS `Name` from `world`.`country` where (`world`.`country`.`Code` like 'A%')",
  "query_plan": {
    "inputs": [
      {
        "ranges": [
          "('A' <= Code <= 'A????????')"
        ],
        "covering": false,
        "operation": "Index range scan on country using PRIMARY over ('A' <= Code <= 'A????????')",
        "index_name": "PRIMARY",
        "table_name": "country",
        "access_type": "index",
        "actual_rows": 17.0,
        "key_columns": [
          "Code"
        ],
        "schema_name": "world",
        "actual_loops": 1,
        "used_columns": [
          "Code",
          "Name"
        ],
        "estimated_rows": 17.0,
        "index_access_type": "index_range_scan",
        "actual_last_row_ms": 0.018502,
        "actual_first_row_ms": 0.015971,
        "estimated_total_cost": 3.668778400708174
      }
    ],
    "condition": "(country.`Code` like 'A%')",
    "operation": "Filter: (country.`Code` like 'A%')",
    "access_type": "filter",
    "actual_rows": 17.0,
    "actual_loops": 1,
    "estimated_rows": 17.0,
    "filter_columns": [
      "world.country.`Code`"
    ],
    "actual_last_row_ms": 0.020957,
    "actual_first_row_ms": 0.017315,
    "estimated_total_cost": 3.668778400708174
  },
  "query_type": "select",
  "json_schema_version": "2.0"
}
1 row in set (0.00 sec)

Вы можете использовать переменную как аргумент функций JSON, чтобы получить определённые элементы информации из значения, например так:

mysql> SELECT JSON_EXTRACT(@v1,'$.index_name') AS iname,
    ->        JSON_EXTRACT(@v1, '$.table_name') AS tname\G
*************************** 1. row ***************************
iname: "PRIMARY"
tname: "country"
1 row in set (0.00 sec)

Этот вид EXPLAIN ANALYZE требует явного FORMAT=JSON, и поддерживается только со SELECT операторами. Также поддерживается необязательный FOR SCHEMA параметр, но он не является обязательным. (FOR DATABASE может использоваться вместо него.) INTO используется с FORMAT=JSON только при значении explain_json_format_version равном 2; в противном случае оператор завершается ошибкой EXPLAIN ANALYZE не поддерживает FORMAT=JSON при explain_json_format_version=1 ().

После использования формата версии 2, вы можете привести вывод JSON от всех последующих EXPLAIN FORMAT=JSON операторов к формату версии 1, установив explain_json_format_version обратно в значение 1 (по умолчанию).

Значение explain_json_format_version определяет версию формата вывода JSON, используемую всеми EXPLAIN операторами, использующими его, независимо от того, используется ли формат JSON из-за явного FORMAT=JSON параметра в данном EXPLAIN операторе или из-за автоматического использования формата JSON в связи с установкой системной переменной explain_format в значение JSON.

С помощью EXPLAIN вы можете увидеть, где следует добавить индексы к таблицам, чтобы оператор выполнялся быстрее с помощью индексов для поиска строк. Вы также можете использовать EXPLAIN для проверки того, объединяет ли оптимизатор таблицы в оптимальном порядке. Чтобы дать подсказку оптимизатору использовать порядок объединения, соответствующий порядку имен таблиц в SELECT операторе, начните оператор с SELECT STRAIGHT_JOIN вместо просто SELECT. (См. Раздел 15.2.13, «Оператор SELECT».)

Иногда трассировка оптимизатора может предоставлять информацию, дополняющую информацию от EXPLAIN. Однако формат и содержание трассировки оптимизатора могут изменяться между версиями. Для получения подробностей см. Раздел 10.15, «Отслеживание оптимизатора».

Если у вас возникла проблема с тем, что индексы не используются, когда, по вашему мнению, они должны использоваться, выполните ANALYZE TABLE для обновления статистики таблиц, таких как мощность ключей, которые могут повлиять на выбор, сделанный оптимизатором. См. Раздел 15.7.3.1, «Оператор ANALYZE TABLE».

Примечание

MySQL Workbench имеет возможность визуального объяснения, которая предоставляет визуальное представление вывода EXPLAIN. См. .

Получение информации с помощью EXPLAIN ANALYZE

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

  • Оценённая стоимость выполнения

    (Некоторые итераторы не учитываются моделью стоимости и, следовательно, не включены в оценку.)

  • Оценённое количество возвращённых строк

  • Время возврата первой строки

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

    (При нескольких циклах эта цифра показывает среднее время за цикл.)

  • Количество строк, возвращённых итератором

  • Количество циклов

Информация о выполнении запроса отображается с помощью формата вывода TREE, в котором узлы представляют итераторы. EXPLAIN ANALYZE использует формат вывода, который можно необязательно указать явно с помощью FORMAT=TREE или FORMAT=JSON; по умолчанию используется TREE. FORMAT=JSON может быть использован только если explain_json_format_version установлен в 2.

EXPLAIN ANALYZE может использоваться с SELECT операторами, многотабличными UPDATE и DELETE операторами и TABLE операторами.

Вы можете прервать этот оператор с помощью KILL QUERY или CTRL-C.

EXPLAIN ANALYZE не может быть использован с FOR CONNECTION.

Пример вывода:

mysql> SELECT @@explain_format;
+------------------+
| @@explain_format |
+------------------+
| TRADITIONAL      |
+------------------+

mysql> EXPLAIN ANALYZE SELECT * FROM t1 JOIN t2 ON (t1.c1 = t2.c2)\G
*************************** 1. row ***************************
EXPLAIN: -> Inner hash join (t2.c2 = t1.c1)  (cost=3.5 rows=5)
(actual time=0.121..0.131 rows=1 loops=1)
    -> Table scan on t2  (cost=0.07 rows=5)
(actual time=0.0126..0.0221 rows=5 loops=1)
    -> Hash
        -> Table scan on t1  (cost=0.75 rows=5)
(actual time=0.0372..0.0534 rows=5 loops=1)

mysql> EXPLAIN ANALYZE FORMAT=TREE SELECT * FROM t3 WHERE i > 8\G
*************************** 1. row ***************************
EXPLAIN: -> Filter: (t3.i > 8)  (cost=0.75 rows=1.67)
(actual time=0.0484..0.0542 rows=1 loops=1)
    -> Table scan on t3  (cost=0.75 rows=5)
(actual time=0.0417..0.0494 rows=5 loops=1)

mysql> EXPLAIN ANALYZE FORMAT=JSON SELECT * FROM t3 WHERE pk < 17\G
*************************** 1. row ***************************
EXPLAIN: {
  "query": "/* select#1 */ select `a`.`t3`.`pk` AS `pk`,`a`.`t3`.`i` AS `i` from `a`.`t3` where (`a`.`t3`.`pk` < 17)",
  "inputs": [
    {
      "ranges": [
        "(pk < 17)"
      ],
      "covering": false,
      "operation": "Index range scan on t3 using PRIMARY over (pk < 17)",
      "index_name": "PRIMARY",
      "table_name": "t3",
      "access_type": "index",
      "actual_rows": 3.0,
      "key_columns": [
        "pk"
      ],
      "schema_name": "a",
      "actual_loops": 1,
      "used_columns": [
        "pk",
        "i"
      ],
      "estimated_rows": 3.0,
      "index_access_type": "index_range_scan",
      "actual_last_row_ms": 0.034214,
      "actual_first_row_ms": 0.03052,
      "estimated_total_cost": 0.860618301731245
    }
  ],
  "condition": "(t3.pk < 17)",
  "operation": "Filter: (t3.pk < 17)",
  "query_type": "select",
  "access_type": "filter",
  "actual_rows": 3.0,
  "actual_loops": 1,
  "estimated_rows": 3.0,
  "filter_columns": [
    "a.t3.pk"
  ],
  "actual_last_row_ms": 0.038189,
  "actual_first_row_ms": 0.033429,
  "estimated_total_cost": 0.860618301731245
}

Таблицы, используемые в примере вывода, были созданы операторами, показанными здесь:

CREATE TABLE t1 (
    c1 INTEGER DEFAULT NULL,
    c2 INTEGER DEFAULT NULL
);

CREATE TABLE t2 (
    c1 INTEGER DEFAULT NULL,
    c2 INTEGER DEFAULT NULL
);

CREATE TABLE t3 (
    pk INTEGER NOT NULL PRIMARY KEY,
    i INTEGER DEFAULT NULL
);

Значения, отображаемые для actual time в выводе этого оператора, выражаются в миллисекундах.

explain_format оказывает следующее воздействие на EXPLAIN ANALYZE:

  • Если значение этой переменной равно TRADITIONAL или TREE (или синоним DEFAULT), EXPLAIN ANALYZE использует формат TREE, если оператор не включает FORMAT=JSON.

  • Если значение explain_format равно JSON, EXPLAIN ANALYZE использует формат JSON, если FORMAT=TREE не указан как часть оператора.

Использование FORMAT=TRADITIONAL или FORMAT=DEFAULT с EXPLAIN ANALYZE всегда приводит к ошибке, независимо от значения explain_format.

В MySQL 9.2 числа в выводе EXPLAIN ANALYZE и EXPLAIN FORMAT=TREE форматируются по следующим правилам:

  • Числа в диапазоне 0,001-999999,5 отображаются как десятичные числа.

    Десятичные числа меньше 1000 отображаются с тремя значащими цифрами; остальные - с четырьмя, пятью или шестью.

  • Числа за пределами диапазона 0,001-999999,5 отображаются в инженерном формате. Примеры таких значений: 1.23e+9 и 934e-6.

  • Не печатаются хвостовые нули. Например, мы отображаем 2.3 вместо 2.30, и 1.2e+6 вместо 1.20e+6.

  • Числа меньше 1e-12 отображаются как 0.

© 2025 Oracle
Licensed under the GPLv2 License.
https://docs.oracle.com/cd/E17952_01/mysql-9.2-en/explain.html

Spec-Zone.ru

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