Различия формата EXPLAIN=JSON от MySQL
EXPLAIN FORMAT=JSON вывод в MySQL и MariaDB.
Вывод JSON EXPLAIN в MariaDB отличается от MySQL. Вот список различий. (В настоящее время они не упорядочены).
Условные обозначения красивее
MySQL печатает условия с избыточным количеством кавычек и фигурных скобок. Кроме того, подзапросы выводятся полностью (несмотря на то, что вы также получаете план для этого подзапроса). Вы видите что-то вроде этого:
"attached_condition": "((`test`.`t1`.`a` < (/* select#2 */ select min(`test`.`t10`.`b`) from `test`.`t10`)) or (`test`.`t1`.`a` > (/* select#3 */ select max(`test`.`t10`.`b`) from `test`.`t10`)))",
"attached_condition": "((`test`.`t20`.`col1` > `test`.`t20`.`col2`) or (`test`.`t20`.`col3` = 4))"
В MariaDB те же условия выводятся так:
"attached_condition": "((t1.a < (subquery#2)) or (t1.a > (subquery#3)))"
"attached_condition": "((t20.col1 > t20.col2) or (t20.col3 = 4))"
Форматировщик JSON умнее
Форматировщик JSON MySQL довольно глуп:
"possible_keys": [
"a"
],
"key": "a",
"used_key_parts": [
"a"
],
Форматировщик JSON MariaDB немного умнее:
"possible_keys": ["a"],
"key": "a",
"key_length": "5",
"used_key_parts": ["a"],
Индексное слияние показывает используемые части ключа
Для ключей с несколькими частями табличный EXPLAIN показывает столбец key_length, оставляя пользователю произвести арифметические вычисления размера столбца, чтобы выяснить, сколько частей ключа используется.
EXPLAIN=JSON MySQL может показать член used_key_parts, который показывает, какие части ключа используются. Для диапазонного доступа также предоставляется key_length:
"access_type": "range",
"possible_keys": [
"col1"
],
"key": "col1",
"used_key_parts": [
"col1",
"col2"
],
"key_length": "10",
Но если вы используете index_merge, вам все равно придется расшифровать key_length:
"table": {
"table_name": "t22",
"access_type": "index_merge",
"possible_keys": [
"col1",
"col3"
],
"key": "sort_union(col1,col3)",
"key_length": "10,5",
"rows": 2398,
В MariaDB вы получаете used_key_parts для всех частей index_merge:
"table_name": "t22",
"access_type": "index_merge",
"possible_keys": ["col1", "col3"],
"key_length": "10,5",
"index_merge": {
"sort_union": {
"range": {
"key": "col1",
"used_key_parts": ["col1", "col2"]
},
"range": {
"key": "col3",
"used_key_parts": ["col3"]
}
}
Диапазон проверяется для каждой записи
В MySQL вам нужно расшифровать битовые карты шестнадцатеричных номеров индексов (как в табличной форме):
"table": {
"table_name": "t2",
"access_type": "ALL",
"possible_keys": [
"key1",
"key3"
],
"rows": 1000,
"filtered": 100,
"range_checked_for_each_record": "index map: 0x5"
}
В MariaDB ключи показаны явно
"range-checked-for-each-record": {
"keys": ["key1", "key3"],
"table": {
"table_name": "t2",
"access_type": "ALL",
"possible_keys": ["key1", "key3"],
"rows": 1000,
"filtered": 100
}
Кроме того, структура отображения ("диапазон проверяется ..." встраивает доступ к таблице) ближе к структуре плана запроса. (TODO: следует ли переместить "диапазон проверяется для каждой записи" внутри "таблицы"? )
Полный поиск по ключу NULL
Табличный EXPLAIN показывает «Полный поиск по ключу NULL» в столбце Extra. MySQL произвел прямой перевод в JSON:
"table": {
"table_name": "t1",
"access_type": "ref_or_null",
...
...
"rows": 2,
"filtered": 100,
"using_index": true,
"full_scan_on_NULL_key": true,
...
}
Это не подходит для MariaDB, так как она хотела бы иметь место для ANALYZE, чтобы показать #петель для каждой конструкции. Это также нелогично — некоторый атрибут в конце говорит «кстати, все вышеперечисленное не используется в некоторых случаях». По этой причине MariaDB использует:
"full-scan-on-null_key": {
"table": {
"table_name": "t1",
"access_type": "ref_or_null",
"possible_keys": ["a"],
"key": "a",
...
}
План буфера объединения показан более подробно
MySQL отображает «использование буфера объединения» как просто другой вид доступа к таблице. Он не разделяет чтение из буфера объединения и запись в буфер объединения.
"nested_loop": [
{
"table": {
"table_name": "A",
"access_type": "ALL",
"rows": 10,
"filtered": 100,
"attached_condition": "(`test`.`A`.`b` = 3)"
}
},
{
"table": {
"table_name": "B",
"access_type": "ALL",
"rows": 20,
"filtered": 100,
"using_join_buffer": "Block Nested Loop",
"attached_condition": "((`test`.`B`.`b` = 4) and ((`test`.`A`.`a` + `test`.`B`.`a`) < 3))"
}
}
MariaDB показывает, что происходит на самом деле:
"table": {
"table_name": "A",
"access_type": "ALL",
"rows": 10,
"filtered": 100,
"attached_condition": "(A.b = 3)"
},
"block-nl-join": {
"table": {
"table_name": "B",
"access_type": "ALL",
"rows": 10,
"filtered": 100,
"attached_condition": "(B.b = 4)"
},
"buffer_type": "flat",
"buffer_size": "128Kb",
"join_type": "BNL",
"attached_condition": "((A.a + B.a) < 3)"
}
TODO: другие различия
© 2023 MariaDB
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.
https://mariadb.com/kb/en/explain-format-json-differences/