blob: 62139af5d49f4a762be1f8762ff00601cf867c95 [file]
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="copyright" content="(C) Copyright 2025" />
<meta name="DC.rights.owner" content="(C) Copyright 2025" />
<meta name="DC.Type" content="concept" />
<meta name="DC.Title" content="EXPLAIN Statement" />
<meta name="DC.Relation" scheme="URI" content="../topics/impala_langref_sql.html" />
<meta name="prodname" content="Impala" />
<meta name="prodname" content="Impala" />
<meta name="version" content="Impala 3.4.x" />
<meta name="version" content="Impala 3.4.x" />
<meta name="DC.Format" content="XHTML" />
<meta name="DC.Identifier" content="explain" />
<link rel="stylesheet" type="text/css" href="../commonltr.css" />
<title>EXPLAIN Statement</title>
</head>
<body id="explain">
<h1 class="title topictitle1" id="ariaid-title1">EXPLAIN Statement</h1>
<div class="body conbody">
<p class="p"> Returns the execution plan for a statement, showing the low-level
mechanisms that Impala will use to read the data, divide the work among
nodes in the cluster, and transmit intermediate and final results across
the network. Use <code class="ph codeph">explain</code> followed by a complete
<code class="ph codeph">SELECT</code> query. For example: </p>
<p class="p">
<strong class="ph b">Syntax:</strong>
</p>
<pre class="pre codeblock"><code>EXPLAIN { <var class="keyword varname">select_query</var> | <var class="keyword varname">ctas_stmt</var> | <var class="keyword varname">insert_stmt</var> }
</code></pre>
<p class="p">
The <var class="keyword varname">select_query</var> is a <code class="ph codeph">SELECT</code> statement, optionally prefixed by a
<code class="ph codeph">WITH</code> clause. See <a class="xref" href="impala_select.html#select">SELECT Statement</a> for details.
</p>
<p class="p">
The <var class="keyword varname">insert_stmt</var> is an <code class="ph codeph">INSERT</code> statement that inserts into or overwrites an
existing table. It can use either the <code class="ph codeph">INSERT ... SELECT</code> or <code class="ph codeph">INSERT ...
VALUES</code> syntax. See <a class="xref" href="impala_insert.html#insert">INSERT Statement</a> for details.
</p>
<p class="p">
The <var class="keyword varname">ctas_stmt</var> is a <code class="ph codeph">CREATE TABLE</code> statement using the <code class="ph codeph">AS
SELECT</code> clause, typically abbreviated as a <span class="q">"CTAS"</span> operation. See
<a class="xref" href="impala_create_table.html#create_table">CREATE TABLE Statement</a> for details.
</p>
<p class="p">
<strong class="ph b">Usage notes:</strong>
</p>
<p class="p">
You can interpret the output to judge whether the query is performing efficiently, and adjust the query
and/or the schema if not. For example, you might change the tests in the <code class="ph codeph">WHERE</code> clause, add
hints to make join operations more efficient, introduce subqueries, change the order of tables in a join, add
or change partitioning for a table, collect column statistics and/or table statistics in Hive, or any other
performance tuning steps.
</p>
<p class="p">
The <code class="ph codeph">EXPLAIN</code> output reminds you if table or column statistics are missing from any table
involved in the query. These statistics are important for optimizing queries involving large tables or
multi-table joins. See <a class="xref" href="impala_compute_stats.html#compute_stats">COMPUTE STATS Statement</a> for how to gather statistics,
and <a class="xref" href="impala_perf_stats.html#perf_stats">Table and Column Statistics</a> for how to use this information for query tuning.
</p>
<div class="p">
Read the <code class="ph codeph">EXPLAIN</code> plan from bottom to top:
<ul class="ul">
<li class="li">
The last part of the plan shows the low-level details such as the expected amount of
data that will be read, where you can judge the effectiveness of your partitioning
strategy and estimate how long it will take to scan a table based on total data size
and the size of the cluster.
</li>
<li class="li">
As you work your way up, next you see the operations that will be parallelized and
performed on each Impala node.
</li>
<li class="li">
At the higher levels, you see how data flows when intermediate result sets are
combined and transmitted from one node to another.
</li>
<li class="li">
See <a class="xref" href="../shared/../topics/impala_explain_level.html#explain_level">EXPLAIN_LEVEL Query Option</a> for details
about the <code class="ph codeph">EXPLAIN_LEVEL</code> query option, which lets you customize how
much detail to show in the <code class="ph codeph">EXPLAIN</code> plan depending on whether you
are doing high-level or low-level tuning, dealing with logical or physical aspects
of the query.
</li>
</ul>
</div>
<p class="p">
If you come from a traditional database background and are not familiar with data warehousing, keep in mind
that Impala is optimized for full table scans across very large tables. The structure and distribution of
this data is typically not suitable for the kind of indexing and single-row lookups that are common in OLTP
environments. Seeing a query scan entirely through a large table is common, not necessarily an indication of
an inefficient query. Of course, if you can reduce the volume of scanned data by orders of magnitude, for
example by using a query that affects only certain partitions within a partitioned table, then you might be
able to optimize a query so that it executes in seconds rather than minutes.
</p>
<p class="p"> The <code class="ph codeph">EXPLAIN</code> output becomes more accurate and informative
as statistics are gathered by the <code class="ph codeph">COMPUTE STATS</code>
statement. Initially, the information about data size and distribution,
such as the number of rows or number of distinct values for each column,
is marked "<code class="ph codeph">unavailable</code>". The <code class="ph codeph">COMPUTE
STATS</code> statement performs the analysis, so a subsequent
<code class="ph codeph">EXPLAIN</code> statement has additional information to use in
deciding how to optimize the distributed query. </p>
<p class="p">
For more information and examples to help you interpret <code class="ph codeph">EXPLAIN</code> output, see
<a class="xref" href="impala_explain_plan.html#perf_explain">Using the EXPLAIN Plan for Performance Tuning</a>.
</p>
<p class="p">
<strong class="ph b">Extended EXPLAIN output:</strong>
</p>
<p class="p"> For performance tuning of complex queries, and capacity
planning (such as using the admission control and resource management
features), you can enable more detailed and informative output for the
<code class="ph codeph">EXPLAIN</code> statement. In the
<span class="keyword cmdname">impala-shell</span> interpreter, issue the command
<code class="ph codeph">SET EXPLAIN_LEVEL=<var class="keyword varname">level</var></code>, where
<var class="keyword varname">level</var> is <code class="ph codeph">MINIMAL</code>,
<code class="ph codeph">STANDARD</code>, <code class="ph codeph">EXTENDED</code>, or
<code class="ph codeph">VERBOSE</code>. </p>
<p class="p"> When extended <code class="ph codeph">EXPLAIN</code> output is enabled,
<code class="ph codeph">EXPLAIN</code> statements print information about estimated
memory requirements, minimum number of virtual cores, and so on. </p>
<p class="p">Starting in <span class="keyword">Impala 3.2</span>, if the
<code class="ph codeph">EXPLAIN_LEVEL</code> option is set to
<code class="ph codeph">EXTENDED</code> level or <code class="ph codeph">VERBOSE</code>, the output
contains the following additional information.</p>
<ul class="ul">
<li class="li">The analyzed query, in the output header. <p class="p">The analyzed query may
have been rewritten to include various optimizations and implicit
casts. See the example below.</p>
</li>
<li class="li">The predicates in the plan output includes the same implicit casts and
literals printed with a cast to show the type.</li>
</ul>
<p class="p">
See <a class="xref" href="impala_explain_level.html#explain_level">EXPLAIN_LEVEL Query Option</a> for details and examples.
</p>
<p class="p">
<strong class="ph b">Examples:</strong>
</p>
<p class="p"> This example shows how the standard <code class="ph codeph">EXPLAIN</code> output
moves from the lowest (physical) level to the higher (logical) levels. </p>
<ol class="ol">
<li class="li">The query begins by scanning a certain amount of data; each node
performs an aggregation operation (evaluating <code class="ph codeph">COUNT(*)</code>)
on some subset of data that is local to that node.</li>
<li class="li">The intermediate results are transmitted back to the coordinator node
(labelled here as the <code class="ph codeph">EXCHANGE</code> node).</li>
<li class="li">Lastly, the intermediate results are summed to display the final
result. </li>
</ol>
<pre class="pre codeblock" id="explain__explain_plan_simple"><code>[impalad-host:21000] &gt; EXPLAIN SELECT COUNT(*) FROM customer_address;
+----------------------------------------------------------+
| Explain String |
+----------------------------------------------------------+
| ... |
| |
| 03:AGGREGATE [FINALIZE] |
| | output: sum(count(*)) |
| | |
| 02:EXCHANGE [UNPARTITIONED] |
| | |
| 01:AGGREGATE |
| | output: count(*) |
| | |
| 00:SCAN HDFS [default.customer_address] |
| partitions=1/1 size=5.25MB |
+----------------------------------------------------------+
</code></pre>
<p class="p">The following example shows an extended <code class="ph codeph">EXPLAIN</code> output.
Note that the analyzed query was rewritten to include:</p>
<ul class="ul">
<li class="li">The 'constant folding' optimization, which simplified the expression
in the original query, '<code class="ph codeph">1000 / 100</code>' to
'<code class="ph codeph">10</code>'.</li>
<li class="li">The implicit casts in the <code class="ph codeph">WHERE</code> clause.</li>
</ul>
<pre class="pre codeblock"><code>EXPLAIN SELECT * FROM functional_kudu.alltypestiny WHERE bigint_col &lt; 1000 / 100;
+----------------------------------------------------------+
| Explain String |
+----------------------------------------------------------+
| ...
| Analyzed query: SELECT * FROM mytable WHERE CAST(bigint_col AS DOUBLE) &lt; CAST(10 AS DOUBLE)
| ...
| 00:SCAN KUDU [functional_kudu.alltypestiny]
| predicates: CAST(bigint_col AS DOUBLE) &lt; CAST(10 AS DOUBLE)
...</code></pre>
<p class="p">
<strong class="ph b">Security considerations:</strong>
</p>
<p class="p">
If these statements in your environment contain sensitive literal values such as credit
card numbers or tax identifiers, Impala can redact this sensitive information when
displaying the statements in log files and other administrative contexts. See
<span class="xref">the documentation for your Apache Hadoop distribution</span> for details.
</p>
<p class="p">
<strong class="ph b">Cancellation:</strong> Cannot be cancelled.
</p>
<p class="p">
<strong class="ph b">HDFS permissions:</strong>
</p>
<p class="p">
The user ID that the <span class="keyword cmdname">impalad</span> daemon runs under,
typically the <code class="ph codeph">impala</code> user, must have read
and execute permissions for all applicable directories in all source tables
for the query that is being explained.
(A <code class="ph codeph">SELECT</code> operation could read files from multiple different HDFS directories
if the source table is partitioned.)
</p>
<p class="p">
<strong class="ph b">Kudu considerations:</strong>
</p>
<p class="p">
The <code class="ph codeph">EXPLAIN</code> statement displays equivalent plan
information for queries against Kudu tables as for queries
against HDFS-based tables.
</p>
<p class="p">
To see which predicates Impala can <span class="q">"push down"</span> to Kudu for
efficient evaluation, without transmitting unnecessary rows back
to Impala, look for the <code class="ph codeph">kudu predicates</code> item in
the scan phase of the query. The label <code class="ph codeph">kudu predicates</code>
indicates a condition that can be evaluated efficiently on the Kudu
side. The label <code class="ph codeph">predicates</code> in a <code class="ph codeph">SCAN KUDU</code>
node indicates a condition that is evaluated by Impala.
For example, in a table with primary key column <code class="ph codeph">X</code>
and non-primary key column <code class="ph codeph">Y</code>, you can see that
some operators in the <code class="ph codeph">WHERE</code> clause are evaluated
immediately by Kudu and others are evaluated later by Impala:
</p>
<pre class="pre codeblock"><code>
EXPLAIN SELECT x,y from kudu_table WHERE
x = 1 AND y NOT IN (2,3) AND z = 1
AND a IS NOT NULL AND b &gt; 0 AND length(s) &gt; 5;
+----------------
| Explain String
+----------------
...
| 00:SCAN KUDU [kudu_table]
| predicates: y NOT IN (2, 3), length(s) &gt; 5
| kudu predicates: a IS NOT NULL, b &gt; 0, x = 1, z = 1
</code></pre>
<p class="p">
Only binary predicates, <code class="ph codeph">IS NULL</code> and <code class="ph codeph">IS NOT NULL</code>
(in <span class="keyword">Impala 2.9</span> and higher), and <code class="ph codeph">IN</code> predicates
containing literal values that exactly match the types in the Kudu table, and do not
require any casting, can be pushed to Kudu.
</p>
<p class="p">
<strong class="ph b">Related information:</strong>
</p>
<p class="p">
<a class="xref" href="impala_select.html#select">SELECT Statement</a>,
<a class="xref" href="impala_insert.html#insert">INSERT Statement</a>,
<a class="xref" href="impala_create_table.html#create_table">CREATE TABLE Statement</a>,
<a class="xref" href="impala_explain_plan.html#explain_plan">Understanding Impala Query Performance - EXPLAIN Plans and Query Profiles</a>
</p>
</div>
<div class="related-links">
<div class="familylinks">
<div class="parentlink"><strong>Parent topic:</strong> <a class="link" href="../topics/impala_langref_sql.html">Impala SQL Statements</a></div>
</div>
</div></body>
</html>