从执行计划全方面了解MySQL优化:千万别让性能堵塞了MySQL!

在MySQL中,执行计划是优化器根据查询语句生成的一种重要的数据结构,它描述了如何通过组合底层操作实现查询的逻辑。当我们编写一条SQL语句时,MySQL会自动对其进行优化,并生成最优的执行计划以实现更快的查询速度。

各位精通MySQL的大佬们,像往常一样,我们经常会遇见一堆SQL查询要处理。作为一个优秀的MySQL的操盘手,不能让这些SQL语句任性地在数据库中胡乱扔,必须要好好管管它们!

但是,面对复杂的SQL语句和复杂的数据库架构,我们如何才能快速和准确地分析查询性能?难道要求神通广大的数据库教父出山帮忙?

不要担心!在MySQL世界中,EXPLAIN命令就像是一个小巧而灵活的工具,能够帮助你轻松解决这些问题。使用它,并结合我们自己的经验和智慧,我们就可以像成功解锁小学奥数一样地优化SQL查询,成为MySQL中的一名优秀演员。

废话不多说,现在就让我们开始吧,让我们去通过熟悉每个查询的执行过程,并用一颗豁达的心态理解每个SQL查询的优化分析!

本文将介绍MySQL执行计划的相关知识。首先我们将介绍执行计划的概念以及MySQL优化器是如何生成执行计划的,然后我们将深入探讨执行计划中各种类型的操作符,最后我们将讨论如何通过执行计划来诊断性能问题。

一、什么是执行计划

执行计划是MySQL优化器为了优化查询而生成的一种数据结构,它记录了数据库系统执行查询时所采取的操作流程,即对查询语句的各部分如何进行处理以最终得到查询结果的过程。执行计划通常被表示为一棵树状结构,节点代表不同的操作符(operator),叶子节点代表访问底层数据的方式,例如表扫描或索引查找等。

获取MySQL查询执行计划的方法有多种,下面介绍两种常用的方法:

1. 使用EXPLAIN命令

EXPLAIN命令可以帮助我们分析查询的执行计划,帮助我们发现潜在的性能问题。我们可以通过以下命令来使用:

 
 

sql

复制代码

EXPLAIN SELECT * FROM employees WHERE salary > 50000;

After executing the above command, MySQL will return a table, which contains information such as the index used by the query statement, the number of rows scanned, and the cost of each step.

2. Using PROFILING

MySQL provides a PROFILING tool that can record the operation time of connections and queries on the MySQL server, including the execution time of each SQL statement and resource consumption. We can enable PROFILING with the following command:

 
 

This

copy code

SET profiling = 1;

Then run the query statement we want to analyze.

Finally, we can view the profile information of the query, for example:

 
 

sql

copy code

SHOW PROFILE ALL FOR QUERY n;

Where n represents the ID of the query statement, which can be obtained through the following command:

 
 

This

copy code

SHOW PROFILES;

The above are the two common methods for obtaining MySQL execution plan. You need to choose different methods to obtain and analyze the execution plan according to the specific situation.

2. Execution plan generation process

During a query, the MySQL optimizer must decide the best execution plan for the query. This process is often called query optimization. The goal of query optimization is to choose the execution plan with the least cost, that is, to choose the fastest execution plan among all possible execution plans. Query optimization can be viewed as a search space problem, where the search space includes all possible execution plans.

The following is the general process for the MySQL optimizer to determine the execution plan:

  1. Parse SQL statements and construct syntax trees. MySQL first parses the SQL statement and represents the query using a syntax tree. A syntax tree consists of various operators and expressions.

For example, the following is a syntax tree for a query statement:

 
 

sql

copy code

SELECT * FROM employees WHERE salary > 50000;

  1. Generate all possible execution plans. Next, the MySQL optimizer will generate all possible execution plans. It tries all possible sequences of operations and access methods to find the optimal execution plan.
  2. Estimate the cost of each execution plan. For each execution plan, MySQL will estimate its cost and choose the execution plan with the least cost. The cost is usually composed of factors such as disk I/O, memory usage, etc.
  3. Execute the query. Finally, MySQL executes the plan and returns the result.

Three, the operator of the execution plan

The operators in the MySQL execution plan are divided into three categories: query plan operators, join operators, and auxiliary operators. Below we will introduce these three operators separately.

1. Query plan operators

Query plan operators include the following types:

  • Table scan: This is a simple operation that retrieves records by traversing the entire table. MySQL does this when the table does not have an index or the index cannot be used for queries.

Example query:

 
 

sql

copy code

SELECT * FROM employees;

  • Index lookup (Index lookup): When the query condition contains index columns or covering indexes, MySQL will use the index lookup operation. This operation is usually much faster than a table scan.

Example query:

 
 

This

copy code

SELECT * FROM employees WHERE emp_id = 1001;

  • Range lookup (Range lookup): When the query condition contains range operators (such as >, <, BETWEEN, IN, etc.), MySQL will use the range lookup operation.

Example query:

 
 

sql

copy code

SELECT * FROM employees WHERE salary BETWEEN 40000 AND 60000;

  • Full text search (Fulltext search): When you need to search for a keyword in the full text, MySQL will use the full text search operation. But it requires the table to have a full-text index.

Example query:

 
 

sql

copy code

SELECT * FROM articles WHERE MATCH(title, body) AGAINST ('MySQL');

  • Sort (Sort): When the query needs to display the results according to the specified sorting rules, MySQL uses sorting operations.

Example query:

 
 

sql

copy code

SELECT * FROM employees ORDER BY salary DESC;

  • Grouping (Group): When the result set needs to be grouped, MySQL will use the grouping operator.

Example query:

 
 

sql

copy code

SELECT department, AVG(salary) FROM employees GROUP BY department;

  • Aggregation (Aggregation): When aggregation operations are required on the entire table or a certain part, MySQL uses aggregation operators.

Example query:

 
 

sql

copy code

SELECT COUNT(*) FROM employees;

2. Concatenation operator

Join operators are used to join data from different data sources. MySQL supports the following join operators:

  • Equal join: When two tables contain the same keyword (that is, foreign key), MySQL will use the equivalent join operator to implement the join operation.

Example query:

 
 

vbnet

copy code

SELECT * FROM employees JOIN departments ON employees.department_id = departments.department_id;

  • Non-equal join (Non-equal join): When the join condition uses non-equal operators (such as >, <, BETWEEN, etc.), MySQL will use non-equal join operators.

Example query:

 
 

vbnet

copy code

SELECT * FROM employees JOIN salaries ON employees.emp_id = salaries.emp_id AND salaries.salary > 50000;

  • Self join: Also known as a self-join operation, it joins a table with itself.

Example query:

 
 

css

copy code

SELECT a.emp_name AS name1, b.emp_name AS name2 FROM employees a, employees b WHERE a.manager_id = b.emp_id;

  • Outer join: When we need to query the records of two tables, regardless of whether the two tables have the same key words, we can use the outer join operator to connect.

Example query:

 
 

sql

copy code

SELECT * FROM employees LEFT JOIN salaries ON employees.emp_id = salaries.emp_id;

3. Auxiliary operators

Auxiliary operators are additional operations in a MySQL execution plan. These operations are commonly used to optimize performance and include the following types:

  • Index merge (Index merge): When a query involves multiple indexes, MySQL will merge these indexes to improve performance.

Example query:

 
 

This

copy code

SELECT * FROM employees WHERE emp_id = 1001 AND salary > 50000;

  • Subquery (Subquery): When a query needs to be nested within another query, MySQL uses the subquery operator.

Example query:

 
 

sql

copy code

SELECT * FROM employees WHERE salary > (SELECT AVG(salary) FROM employees);

  • Temporary table (Temporary table): When the query involves a large amount of data or there is a complex connection relationship, MySQL will create a temporary table on disk to process the query.

Example query:

 
 

vbnet

copy code

SELECT * FROM employees JOIN salaries JOIN departments ON employees.emp_id = salaries.emp_id AND employees.department_id = departments.department_id;

The above is the introduction of various operators in the MySQL execution plan. These operators play an important role in execution plan generation and performance optimization.

4. Diagnosis and Analysis of Execution Plan

When we find that there is a problem with the performance of MySQL, we can diagnose the performance problem through the execution plan. Here are some common techniques:

1. Use the EXPLAIN command

The EXPLAIN command can help us analyze the execution plan of the query and help us find potential performance problems. We can use the following command:

 
 

sql

copy code

EXPLAIN SELECT * FROM employees WHERE salary > 50000;

The output will tell us the sequence of operations and access methods taken by MySQL, as well as the cost of each operation.

2. Check the index

In many cases, we can improve query performance by adding appropriate indexes. We can check the indexes on the table with the following command:

 
 

sql

copy code

SHOW INDEXES FROM employees;

The output will tell us the name of the index, its type, and the columns it contains.

3. Analyze query logs

We can analyze the execution of the query by viewing the MySQL query log. We can enable query logging with the following command:

 
 

This

copy code

SET GLOBAL general_log = 'ON';

We can then view the query log file, for example:

 
 

bash

copy code

tail -f /var/log/mysql/general.log

These are the basic techniques for diagnosing MySQL performance problems using execution plans. In actual work, we can use different methods to analyze execution plans and optimize query performance according to specific situations.

5. How to analyze the EXPLAIN results?

After using the EXPLAIN command to get the MySQL query execution plan, we need to analyze the results to identify potential performance problems. The following are some commonly used analysis methods:

1. Scan type

Scan Type (Scan Type) is an indicator displayed in the Query Plan Time Consumed column. Through this indicator, we can understand whether MySQL uses indexes or full table scans to access data. Typically, scan types such as ALL, index, and range indicate that performance may be impacted. in:

  • ALL means a full table scan, that is, the data of the entire table is scanned.
  • index indicates that index scanning is used, but the required records need to be found in the index.
  • range indicates that the index range search is used, that is, a partial index is used for search.

2. Association type

The association type refers to the algorithm used in the join operation. If association types such as Equa Join, Ref, and Index Merge appear in the query plan, it means that MySQL can make full use of indexes when executing queries, which usually improves query performance. in:

  • Equa Join means that MySQL uses an equivalent connection (inner connection) to process rows with the same key value in two tables.
  • Ref indicates that MySQL uses non-equivalent connections to process rows with different key values ​​in the two tables.
  • Index Merge indicates that MySQL uses an index merge algorithm to merge multiple indexes to speed up queries.

3. Access Type

Access type (Access Type) refers to how MySQL obtains data when executing a query. Common access types include:

  • Index: Indicates that the covering index is used to access the data in the table, that is, the required data can be obtained only by using the index.
  • Index-full scan: Indicates that the full table scan index is used to obtain data, but only the data in the index part is accessed.
  • Full-text: Indicates that full-text search is used to obtain data.

4. Row Count Estimation

The rows column in the query plan indicates the number of rows MySQL estimates when executing a certain step. If the table being queried is large or has a large amount of data, the row count estimate may be biased. In this case, we need to pay special attention to the specific query steps and access types to determine whether there are performance problems.

5. Performance optimization

According to the query execution plan, we can judge whether there is a performance bottleneck, and the SQL query statement needs to be optimized. Optimization recommendations depend on the specific query plan, for example:

  • Indexes are used in the query plan, make sure to use the correct indexes and create suitable indexes to support the query.
  • If the query plan uses a full table scan, try to reduce the amount of data queried to avoid a full table scan.
  • If file sorting or temporary table operations occur in the query plan, consider changing the query statement or optimizing the table structure to avoid these operations.

6. Scene analysis

Give you a specific example to explain in detail how to analyze the EXPLAIN results.

Suppose we have the following query:

 
 

sql

copy code

EXPLAIN SELECT * FROM orders o JOIN customers c ON o.customer_id = c.customer_id WHERE o.order_date >= '2022-01-01' AND c.address LIKE '%Beijing%';

The resulting query plan results are as follows:

 
 

sql

copy code

+----+-------------+-------+------------+------+---------------+------+---------+-----------------------------+------+----------+----------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+------+---------------+------+---------+-----------------------------+------+----------+----------------+ | 1 | SIMPLE | c | NULL | ALL | PRIMARY | NULL | NULL | NULL | 1000 | 100.00 | Using where | | 1 | SIMPLE | o | NULL | ref | customer_id | customer_id | 4 | worldsql.c.customer_id | 2 | 11.11 | Using index | +----+-------------+-------+------------+------+---------------+------+---------+-----------------------------+------+----------+----------------+

Based on the results of this query plan, we can perform the following analysis:

(1) Scan type

In this query plan, the first row indicates that the scan type of the customers table is ALL, that is, a full table scan is performed. This usually slows down MySQL query performance, so we should check that proper indexes are created on the table to optimize the query.

(2) Association type

关联类型是 SIMPLE,表示这是一个简单的非子查询。同时,我们还可以看到这里使用了 Equa Join 算法,即使用内连接处理两张表中相同键值的行。这通常是MySQL执行联接操作时的最佳算法之一。

(3)访问类型

在这个查询计划中,我们还可以看到,orders 表使用了 ref 访问类型,即使用了索引扫描来获取所需数据。这通常比全表扫描更加高效,因此这是一个好的访问类型。

(4) 行数估算

在这个查询计划中,rows 行数估算列显示为 1000,而实际上 customers 表中只有 1000 行。这意味着MySQL执行了全表扫描并扫描了整个表的所有行。这通常会影响查询性能,因此我们应该检查表上是否存在适当的索引。

(5)性能优化

针对以上分析结果,我们可以考虑以下优化策略:

  • 创建索引:为 customers 表上的 address 列创建索引,以避免全表扫描。
  • 设计合适的索引:为 orders 表上的 order_date 和 customer_id 列创建复合索引来支持查询,可以进一步提高查询性能。

实际sql查询执行,借助通过分析 EXPLAIN 的结果,我们可以确定如何针对性地优化查询语句以提高性能。

六、小结一下

EXPLAIN 命令就像是一个卧虎藏龙的武林秘籍,使用它能够让MySQL查询变得轻松愉快。在这里,我们可以看到每个查询都是一场表演,有着自己的角色和特点。

扫描类型就像是一个吃货,它会吃遍整个表才能满足胃口;而关联类型就像是一个心机婊,它总是喜欢暗示你要去找另外的表玩耍。而访问类型则是一个聪明的程序员,它总是想方设法通过索引快速获取所需数据。

然而,行数估算却像是一个嘴巴不太靠谱的推销员,它总是高估自己的能力,并且喜欢随意地浪费时间和精力。

幸运的是,在这个MySQL世界中,你永远不会孤单。通过使用 EXPLAIN 命令并对查询计划结果进行分析,我们可以更好地理解MySQL执行查询的过程,找到性能瓶颈,并采取相应的优化措施。

Finally, remember: Optimizing MySQL queries requires not only skill, but also patience and perseverance. However, when you see that the query plan is significantly optimized, you will feel full of strength and confidence!

Without further ado, MySQL is a powerful database system that can be used in many different scenarios. In order to realize its maximum performance potential, we need a deep understanding of MySQL's execution plan and query optimization techniques, and use this knowledge to diagnose and optimize query performance.

おすすめ

転載: blog.csdn.net/wdj_yyds/article/details/131725864