# Understanding SQL Queries Using the EXPLAIN Command

<div><strong>Source</strong>: <a href='https://www.tuanh.net/blog/devops/understanding-sql-queries-using-the-explain-command'>Understanding SQL Queries Using the EXPLAIN Command</a></div><div class="line-post"> 
 <h2 class="title-post">1. What is the EXPLAIN Command?</h2> 
</div>
<div class="line-post">
  The <strong>EXPLAIN</strong> command is a powerful SQL feature that allows you to view the query execution plan. The execution plan is a breakdown of how the SQL engine will process your query, from selecting the best indexes to applying joins, filtering, and sorting. With this tool, you can spot potential bottlenecks and inefficiencies in your query. 
</div>
<div class="images-post"> 
 <img width="80%" class="element_406466-image" src="https://resource.tuanh.net/article/image/fc4aef19-f679-4287-92c4-0a068ca8e7e8.png" alt="Image"> 
</div>
<div class="line-post"> 
 <h3 class="sub1">1.1 Understanding the Basics of EXPLAIN</h3> 
</div>
<div class="line-post">
  The simplest way to use <strong>EXPLAIN </strong>is to prefix your SQL query with the <strong>EXPLAIN </strong>keyword. For example: 
</div>
<pre class="code">EXPLAIN SELECT * FROM employees WHERE department = 'HR';</pre>
<div class="line-post">
  Running this query doesn’t return the actual data; instead, it provides a detailed breakdown of how the SQL engine plans to execute this query. 
</div>
<div class="line-post"> 
 <h3 class="sub1">1.2 The Output of EXPLAIN</h3> 
</div>
<div class="line-post">
  The output of EXPLAIN generally consists of several columns, including but not limited to: 
</div>
<div class="line-post"> 
 <ul> 
  <li><strong>id</strong>: Identifies the order of execution.</li> 
  <li><strong>select_type</strong>: Describes the type of query (e.g., SIMPLE, SUBQUERY).</li> 
  <li><strong>table</strong>: Indicates which table is being accessed.</li> 
  <li><strong>type</strong>: Shows the type of join (e.g., ALL, INDEX, REF).</li> 
  <li><strong>possible_keys</strong>: Lists potential indexes that could be used.</li> 
  <li><strong>key</strong>: Specifies the actual index chosen by the query planner.</li> 
  <li><strong>rows</strong>: Estimated number of rows that will be scanned.</li> 
  <li><strong>extra</strong>: Additional information, such as whether filesort or temporary tables are being used.</li> 
 </ul> 
</div>
<div class="line-post">
  Let’s break down the importance of these fields. 
</div>
<div class="line-post"> 
 <h3 class="sub1">1.3 Why These Fields Matter</h3> 
</div>
<div class="line-post"> 
 <ul> 
  <li><strong>id</strong>: This field helps you understand the order in which your SQL statements are executed, especially for complex queries with subqueries.</li> 
  <li><strong>select_type</strong>: Identifies whether the query is SIMPLE, PRIMARY, or a SUBQUERY. This gives insights into the complexity of the query.</li> 
  <li><strong>possible_keys and key</strong>: The keys (indexes) are critical because they determine how fast the database can access the data. If no index is used, it’s a red flag for potential performance issues.</li> 
 </ul> 
</div>
<div class="line-post"> 
 <h3 class="sub1">1.4 A Simple Example</h3> 
</div>
<div class="line-post">
  Consider a simple query to fetch employees from the HR department: 
</div>
<pre class="code">EXPLAIN SELECT * FROM employees WHERE department = 'HR';</pre>
<div class="line-post">
  The output might look something like this: 
</div>
<div class="line-post"> 
 <table> 
  <tbody> 
   <tr> 
    <td><strong>id</strong></td> 
    <td><strong>select_type</strong></td> 
    <td><strong>table</strong></td> 
    <td><strong>type</strong></td> 
    <td><strong>possible_keys</strong></td> 
    <td><strong>key</strong></td> 
    <td><strong>rows</strong></td> 
    <td><strong>Extra</strong></td> 
   </tr> 
   <tr> 
    <td>1</td> 
    <td>SIMPLE</td> 
    <td>employees</td> 
    <td>ref</td> 
    <td>department</td> 
    <td>dept</td> 
    <td>50</td> 
    <td>Using where<br></td> 
   </tr> 
  </tbody> 
 </table> 
</div>
<div class="line-post">
  Here, the <strong>EXPLAIN </strong>result shows that the database will use the <strong>dept </strong>index and will scan approximately 50 rows. This is an efficient query, as the database is leveraging an index to limit the number of rows it needs to evaluate. 
</div>
<div class="line-post"> 
 <h2 class="title-post">2. Optimizing Queries with EXPLAIN</h2> 
</div>
<div class="line-post">
  Knowing how to interpret the output of EXPLAIN is crucial for optimizing SQL queries. Let's dive deeper into specific scenarios where EXPLAIN can guide you toward optimization. 
</div>
<div class="line-post"> 
 <h3 class="sub1">2.1 Identifying Full Table Scans</h3> 
</div>
<div class="line-post">
  One common issue with SQL queries is full table scans, which can significantly slow down query performance, especially on large tables. A full table scan means that the database has to evaluate every row in the table to determine which rows match the query. 
</div>
<div class="line-post">
  For instance, if you run this query: 
</div>
<pre class="code">EXPLAIN SELECT * FROM orders WHERE order_date = '2023-09-01';</pre>
<div class="line-post">
  And see output like this: 
</div>
<div class="line-post"> 
 <table> 
  <tbody> 
   <tr> 
    <td><strong>id</strong></td> 
    <td><strong>select_type</strong></td> 
    <td><strong>table</strong></td> 
    <td><strong>type</strong></td> 
    <td><strong>possible_keys</strong></td> 
    <td><strong>key</strong></td> 
    <td><strong>rows</strong></td> 
    <td><strong>Extra</strong></td> 
   </tr> 
   <tr> 
    <td>1</td> 
    <td>SIMPLE</td> 
    <td>orders</td> 
    <td>ALL</td> 
    <td>NULL</td> 
    <td>NULL</td> 
    <td>1000</td> 
    <td>Using where<br></td> 
   </tr> 
  </tbody> 
 </table> 
</div>
<div class="line-post">
  In this case, the <strong>ALL </strong>type and <strong>NULL </strong>keys indicate that no index is being used, and the database will scan all 1,000 rows. Adding an index on <strong>order_date </strong>could significantly improve performance. 
</div>
<pre class="code">CREATE INDEX idx_order_date ON orders(order_date);</pre>
<div class="line-post">
  Running the same query again might result in: 
</div>
<div class="line-post"> 
 <table> 
  <tbody> 
   <tr> 
    <td><strong>id</strong></td> 
    <td><strong>select_type</strong></td> 
    <td><strong>table</strong></td> 
    <td><strong>type</strong></td> 
    <td><strong>possible_keys</strong></td> 
    <td><strong>key</strong></td> 
    <td><strong>rows</strong></td> 
    <td><strong>Extra</strong></td> 
   </tr> 
   <tr> 
    <td>1</td> 
    <td>SIMPLE</td> 
    <td>orders</td> 
    <td>ref</td> 
    <td>idx_order_date</td> 
    <td>idx_order_date</td> 
    <td>100</td> 
    <td>Using where<br></td> 
   </tr> 
  </tbody> 
 </table> 
</div>
<div class="line-post">
  The query planner now uses the <strong>idx_order_date </strong>index, scanning only 100 rows instead of 1,000, which is a clear improvement in efficiency. 
</div>
<div class="line-post"> 
 <h3 class="sub1">2.2 Optimizing Joins</h3> 
</div>
<div class="line-post">
  When working with multiple tables, joins are inevitable. However, improper join types can also lead to performance issues. Let’s examine a join query: 
</div>
<pre class="code">EXPLAIN SELECT employees.name, departments.dept_name <br>FROM employees <br>JOIN departments ON employees.dept_id = departments.id <br>WHERE employees.salary &gt; 50000;</pre>
<div class="line-post">
  The output might look like this: 
</div>
<div class="line-post"> 
 <table> 
  <tbody> 
   <tr> 
    <td><strong>id</strong></td> 
    <td><strong>select_type</strong></td> 
    <td><strong>table</strong></td> 
    <td><strong>type</strong></td> 
    <td><strong>possible_keys</strong></td> 
    <td><strong>key</strong></td> 
    <td><strong>rows</strong></td> 
    <td><strong>Extra</strong></td> 
   </tr> 
   <tr> 
    <td>1</td> 
    <td>SIMPLE</td> 
    <td>departments</td> 
    <td>ALL</td> 
    <td>PRIMARY</td> 
    <td>NULL</td> 
    <td>50</td> 
    <td></td> 
   </tr> 
   <tr> 
    <td>1</td> 
    <td>SIMPLE</td> 
    <td>employees</td> 
    <td>ref</td> 
    <td>dept_id</td> 
    <td>dept_id</td> 
    <td>100</td> 
    <td>Using where<br></td> 
   </tr> 
  </tbody> 
 </table> 
</div>
<div class="line-post">
  Here, the <strong>ALL </strong>join type on the <strong>departments </strong>table indicates a full table scan, which could be inefficient for large datasets. You can optimize this by adding an index on <strong>departments.id</strong>: 
</div>
<pre class="code">CREATE INDEX idx_dept_id ON departments(id);</pre>
<div class="line-post">
  Now, the query optimizer can use the index, reducing the rows scanned in the join process. 
</div>
<div class="line-post"> 
 <h3 class="sub1">2.3 Avoiding Filesorts</h3> 
</div>
<div class="line-post">
  In some cases, you might see <strong>Using filesort</strong> in the <strong>Extra </strong>column of your <strong>EXPLAIN </strong>output. This indicates that the database is sorting the results in memory, which can be inefficient for large datasets. You can avoid filesorts by indexing the columns that are used in the <strong>ORDER BY</strong> clause. 
</div>
<div class="line-post">
  For example: 
</div>
<pre class="code">EXPLAIN SELECT * FROM employees ORDER BY name;</pre>
<div class="line-post">
  If the output shows <strong>Using filesort</strong>, creating an index on <strong>name </strong>will help: 
</div>
<pre class="code">CREATE INDEX idx_name ON employees(name);</pre>
<div class="line-post">
  Running the <strong>EXPLAIN </strong>again should show improved performance without a filesort. 
</div>
<div class="line-post"> 
 <h2 class="title-post">3. Conclusion</h2> 
</div>
<div class="line-post">
  Using the <strong>EXPLAIN </strong>command is essential for optimizing your SQL queries and ensuring they run efficiently. By understanding the output of <strong>EXPLAIN</strong>, such as the use of indexes, the type of joins, and potential issues like full table scans or filesorts, you can make informed decisions about query optimization. Regularly using <strong>EXPLAIN </strong>will not only improve your query performance but also deepen your understanding of how databases process SQL queries. 
</div>
<div class="line-post">
  If you have any questions or need further clarification, feel free to leave a comment below. 
</div><p><strong>Read more at </strong>: <a href='https://www.tuanh.net/blog/devops/understanding-sql-queries-using-the-explain-command'>Understanding SQL Queries Using the EXPLAIN Command</a></p>
