SHOW PLAN
is an SQL statement that displays the execution plan of the previous SELECT
statement. The plan is generated and stored during the actual execution, so profiling must be enabled in the current session before running that statement. This can be done with a SET profiling=1
statement.
To view the query execution plan in JSON queries, add "profile": true
to the query. The result appears as a profile
property in the result set.
Note that there are two things returned in the SQL mode: * transformed_tree
, which shows the full-text query decomposition * enabled_indexes
, which shows information about effective secondary indexes
set profiling=1;
select * from hn_small where match('dog|cat') limit 0;
plan; show
*************************** 1. row ***************************
Variable: transformed_treeValue: OR(
AND(KEYWORD(dog, querypos=1)),
AND(KEYWORD(cat, querypos=2)))
*************************** 2. row ***************************
Variable: enabled_indexesValue:
2 rows in set (0.00 sec)
POST /search
{
"index": "hn_small",
"query": {"query_string": "dog|cat"},
"_source": { "excludes":["*"] },
"limit": 0,
"profile":true
}
{
"took": 0,
"timed_out": false,
"hits": {
"total": 4453,
"total_relation": "eq",
"hits": []
},
"profile": {
"query": {
"type": "OR",
"description": "OR( AND(KEYWORD(dog, querypos=1)), AND(KEYWORD(cat, querypos=2)))",
"children": [
{
"type": "AND",
"description": "AND(KEYWORD(dog, querypos=1))",
"children": [
{
"type": "KEYWORD",
"word": "dog",
"querypos": 1
}
]
},
{
"type": "AND",
"description": "AND(KEYWORD(cat, querypos=2))",
"children": [
{
"type": "KEYWORD",
"word": "cat",
"querypos": 2
}
]
}
]
}
}
}
In some cases, the evaluated query tree can be quite different from the original one due to expansions and other transformations.
SET profiling=1;
SELECT id FROM forum WHERE MATCH('@title way* @content hey') LIMIT 1;
PLAN; SHOW
Query OK, 0 rows affected (0.00 sec)
+--------+
id |
| +--------+
711651 |
| +--------+
1 row in set (0.04 sec)
+------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
Value |
| Variable | +------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
AND(
| transformed_tree | OR(
OR(
AND(fields=(title), KEYWORD(wayne, querypos=1, expanded)),
OR(
AND(fields=(title), KEYWORD(ways, querypos=1, expanded)),
AND(fields=(title), KEYWORD(wayyy, querypos=1, expanded)))),
AND(fields=(title), KEYWORD(way, querypos=1, expanded)),
OR(fields=(title), KEYWORD(way*, querypos=1, expanded))),
AND(fields=(content), KEYWORD(hey, querypos=2))) |
+------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
POST /search
{
"index": "forum",
"query": {"query_string": "@title way* @content hey"},
"_source": { "excludes":["*"] },
"limit": 1,
"profile": true
}
{
"took":33,
"timed_out":false,
"hits":
{
"total":105,
"hits":
[
{
"_id":"711651",
"_score":2539,
"_source":{}
}
]
},
"profile":
{
"query":
{
"type":"AND",
"description":"AND( OR( OR( AND(fields=(title), KEYWORD(wayne, querypos=1, expanded)), OR( AND(fields=(title), KEYWORD(ways, querypos=1, expanded)), AND(fields=(title), KEYWORD(wayyy, querypos=1, expanded)))), AND(fields=(title), KEYWORD(way, querypos=1, expanded)), OR(fields=(title), KEYWORD(way*, querypos=1, expanded))), AND(fields=(content), KEYWORD(hey, querypos=2)))",
"children":
[
{
"type":"OR",
"description":"OR( OR( AND(fields=(title), KEYWORD(wayne, querypos=1, expanded)), OR( AND(fields=(title), KEYWORD(ways, querypos=1, expanded)), AND(fields=(title), KEYWORD(wayyy, querypos=1, expanded)))), AND(fields=(title), KEYWORD(way, querypos=1, expanded)), OR(fields=(title), KEYWORD(way*, querypos=1, expanded)))",
"children":
[
{
"type":"OR",
"description":"OR( AND(fields=(title), KEYWORD(wayne, querypos=1, expanded)), OR( AND(fields=(title), KEYWORD(ways, querypos=1, expanded)), AND(fields=(title), KEYWORD(wayyy, querypos=1, expanded))))",
"children":
[
{
"type":"AND",
"description":"AND(fields=(title), KEYWORD(wayne, querypos=1, expanded))",
"fields":["title"],
"max_field_pos":0,
"children":
[
{
"type":"KEYWORD",
"word":"wayne",
"querypos":1,
"expanded":true
}
]
},
{
"type":"OR",
"description":"OR( AND(fields=(title), KEYWORD(ways, querypos=1, expanded)), AND(fields=(title), KEYWORD(wayyy, querypos=1, expanded)))",
"children":
[
{
"type":"AND",
"description":"AND(fields=(title), KEYWORD(ways, querypos=1, expanded))",
"fields":["title"],
"max_field_pos":0,
"children":
[
{
"type":"KEYWORD",
"word":"ways",
"querypos":1,
"expanded":true
}
]
},
{
"type":"AND",
"description":"AND(fields=(title), KEYWORD(wayyy, querypos=1, expanded))",
"fields":["title"],
"max_field_pos":0,
"children":
[
{
"type":"KEYWORD",
"word":"wayyy",
"querypos":1,
"expanded":true
}
]
}
]
}
]
},
{
"type":"AND",
"description":"AND(fields=(title), KEYWORD(way, querypos=1, expanded))",
"fields":["title"],
"max_field_pos":0,
"children":
[
{
"type":"KEYWORD",
"word":"way",
"querypos":1,
"expanded":true
}
]
},
{
"type":"OR",
"description":"OR(fields=(title), KEYWORD(way*, querypos=1, expanded))",
"fields":["title"],
"max_field_pos":0,
"children":
[
{
"type":"KEYWORD",
"word":"way*",
"querypos":1,
"expanded":true
}
]
}
]
},
{
"type":"AND",
"description":"AND(fields=(content), KEYWORD(hey, querypos=2))",
"fields":["content"],
"max_field_pos":0,
"children":
[
{
"type":"KEYWORD",
"word":"hey",
"querypos":2
}
]
}
]
}
}
}
See also EXPLAIN QUERY. It displays the execution tree of a full-text query without actually executing the query.
query
property contains the transformed full-text query tree. Each node contains:
type
: node type. Can be AND
, OR
, PHRASE
, KEYWORD
, etc.description
: query subtree for this node shown as a string (in SHOW PLAN
format)children
: child nodes, if anymax_field_pos
: maximum position within a fieldword
: transformed keyword. Keyword nodes only.querypos
: position of this keyword in a query. Keyword nodes only.excluded
: keyword excluded from query. Keyword nodes only.expanded
: keyword added by prefix expansion. Keyword nodes only.field_start
: keyword must occur at the very start of the field. Keyword nodes only.field_end
: keyword must occur at the very end of the field. Keyword nodes only.boost
: keyword IDF will be multiplied by this. Keyword nodes only.SHOW PLAN format=dot
allows returning the full-text query execution tree in a hierarchical format suitable for visualization by existing tools, such as https://dreampuf.github.io/GraphvizOnline:
none)]> show plan option format=dot\G
MySQL [(*************************** 1. row ***************************
Variable: transformed_treeValue: digraph "transformed_tree"
{
0 [shape=record,style=filled,bgcolor="lightgrey" label="AND"]
0 -> 1
1 [shape=record,style=filled,bgcolor="lightgrey" label="AND"]
1 -> 2
2 [shape=record label="i | { querypos=1 }"]
0 -> 3
3 [shape=record,style=filled,bgcolor="lightgrey" label="AND"]
3 -> 4
4 [shape=record label="me | { querypos=2 }"]
}