How to analyze the performance of a sql

Copyright: Original article reproduced please indicate the source. https://blog.csdn.net/samll_snail/article/details/90765846

 

This article will explain to you about how to use the analysis a sql.

 

In fact, the Internet has a lot of very detailed introduction of the article explain the use of, this article will combine examples and principles, try to make you have a better understanding, trust me, you should have carefully read the special harvest .

 

explain translates to explain the meaning, it is referred to in the mysql in the implementation plan , which can decide how to implement the article mysql sql After the analysis is optimized seen by the command.

 

Speaking optimizer, more to say, mysql built a powerful optimizer, optimization is the main task is to give you write sql optimize it as much as possible at a lower cost to perform, such as scanning fewer lines number, to avoid sorting. Execute a sql statement have experienced what?  In previous articles I have introduced the optimizer-related.

 

You may ask, at what time will generally use explain it, most cases are from the mysql slow query log pulling out some of the slower sql query efficiency to explain the use of analysis, but also some that is optimized for mysql when, for example, add an index to analyze the index by adding the ability to explain is hit, when there is business development, in the case of needs, you may need to choose a more efficient through sql explain.

 

So explain how to use it, very simple, sql plus explain directly in front of the line, as shown below.

 

mysql> explain select * from t;
+----+-------------+-------+------+---------------+------+---------+------+--------+-------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows   | Extra |
+----+-------------+-------+------+---------------+------+---------+------+--------+-------+
|  1 | SIMPLE      | t     | ALL  | NULL          | NULL | NULL    | NULL | 100332 | NULL  |
+----+-------------+-------+------+---------------+------+---------+------+--------+-------+
1 row in set (0.04 sec)

 

You can see, explain returns of about 10 fields, the field returned different versions slightly different, each field represents a specific meaning, I do not intend this article to each field are described in detail again, more things , you are not afraid of hard to remember a few important fields would leave a good understanding.

 

Which type, key, rows, Extra these fields I think is more important, we are going to help you better understand the meaning of these fields through specific examples.

 

First of all it is necessary to briefly literally under these fields.

 

mysql data represents the type of access, common with a full table scan (all), traversing the index (index), the query interval (range), or the equivalent constant query (ref, eq_ref), the equivalent of a primary key query (const), when when only one record in the table (system). The following is an efficient ordered from best to worst.

 

system > const > eq_ref > ref > range > index > all

 

key index represents the actual name of the query process will be used.

 

rows indicate the number of lines of inquiry may be required scanning process, this data is not necessarily accurate, is a mysql data sampling statistics.

 

Extra indicate some additional information, usually show whether use of the index, the need to sort, whether it will use the temporary table and so on.

 

 

 

Well, then start a formal case study.

 

To continue the previous article or storage engine was created to create a test table, insert 10 w bar test data here, the table structure is as follows:

 

CREATE TABLE `t` (
  `id` int(11) NOT NULL,
  `a` int(11) DEFAULT NULL,
  `b` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB;

 

Then look at the following query statement, pay attention to the table there is only one primary key index, the general index has not been created.

 

mysql> explain select * from t;
+----+-------------+-------+------+---------------+------+---------+------+--------+-------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows   | Extra |
+----+-------------+-------+------+---------------+------+---------+------+--------+-------+
|  1 | SIMPLE      | t     | ALL  | NULL          | NULL | NULL    | NULL | 100332 | NULL  |
+----+-------------+-------+------+---------------+------+---------+------+--------+-------+
1 row in set (0.04 sec)

 

Where type is ALL, represents the full table scan, we see rows attention to this field displays have 100,332, we actually total of only 10w of data, so this is just a field of mysql estimate, not necessarily accurate. This efficiency full table scan is very low, the focus needs to be optimized.

 

Next we were to add a field to ordinary index and b, and watch it again after adding a few sql index.

 

mysql> alter table t add index a_index(a);
Query OK, 0 rows affected (0.19 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> alter table t add index b_index(b);
Query OK, 0 rows affected (0.20 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> show index from t;
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| t     |          0 | PRIMARY  |            1 | id          | A         |      100332 |     NULL | NULL   |      | BTREE      |         |               |
| t     |          1 | a_index  |            1 | a           | A         |      100332 |     NULL | NULL   | YES  | BTREE      |         |               |
| t     |          1 | b_index  |            1 | b           | A         |      100332 |     NULL | NULL   | YES  | BTREE      |         |               |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
3 rows in set (0.00 sec)

 

 

mysql> explain select * from t where a > 1000;
+----+-------------+-------+------+---------------+------+---------+------+--------+-------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows   | Extra       |
+----+-------------+-------+------+---------------+------+---------+------+--------+-------------+
|  1 | SIMPLE      | t     | ALL  | a_index       | NULL | NULL    | NULL | 100332 | Using where |
+----+-------------+-------+------+---------------+------+---------+------+--------+-------------+
1 row in set (0.00 sec)

 

This sql above is a bit puzzled looks of it, type show just is not even a field to add an index yet, but possible_keys also shows there a_index available, but the key to display null, meaning do not actually use a mysql index, this is why?

 

This is because the select *, then also need to look back to the primary key index b field, this process is called back to the table , this statement will filter out the data to meet the conditions of Article 9w, 9w of data means that it will need to return to the operating table, the whole table scans are only 10w of data, so might as well had a full table scan optimizer mysql seems, at least back to the table but also eliminates the process.

 

Of course, it does not mean that as long as the operation will not hit back to the table index, with the index do not think the key lies in mysql query which lower the cost, we put above sql in conditions where again slightly modified look.

 

mysql> explain select * from t where a > 99000;
+----+-------------+-------+-------+---------------+---------+---------+------+------+-----------------------+
| id | select_type | table | type  | possible_keys | key     | key_len | ref  | rows | Extra                 |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-----------------------+
|  1 | SIMPLE      | t     | range | a_index       | a_index | 5       | NULL |  999 | Using index condition |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-----------------------+
1 row in set (0.00 sec)

 

This time, type a value range, key to a_index, hit a representation index, it is a good choice, because only the 1000 data to meet the conditions of this sql, mysql think back to 1000, even if the data table is also better than the full table low cost of scanning, so that mysql is actually a very smart guy.

 

We can also see the Extra field value Using index condition, this means that to use the index, but the need to return to the table, look at this statement.

 

mysql> explain select a from t where a > 99000;
+----+-------------+-------+-------+---------------+---------+---------+------+------+--------------------------+
| id | select_type | table | type  | possible_keys | key     | key_len | ref  | rows | Extra                    |
+----+-------------+-------+-------+---------------+---------+---------+------+------+--------------------------+
|  1 | SIMPLE      | t     | range | a_index       | a_index | 5       | NULL |  999 | Using where; Using index |
+----+-------------+-------+-------+---------------+---------+---------+------+------+--------------------------+
1 row in set (0.00 sec)

 

The value of this Extra Using where; Using index, indicates that the query uses an index field and be able to get to be queried in the index, does not need back to the table, it is clear that to be more efficient than the above, so do not easily write select *, only the query fields to business needs, so you can avoid as much as possible back to the table.

 

Let's look at a sort of need.

 

mysql> explain select a from t where a > 99000 order by b;
+----+-------------+-------+-------+---------------+---------+---------+------+------+---------------------------------------+
| id | select_type | table | type  | possible_keys | key     | key_len | ref  | rows | Extra                                 |
+----+-------------+-------+-------+---------------+---------+---------+------+------+---------------------------------------+
|  1 | SIMPLE      | t     | range | a_index       | a_index | 5       | NULL |  999 | Using index condition; Using filesort |
+----+-------------+-------+-------+---------------+---------+---------+------+------+---------------------------------------+
1 row in set (0.00 sec)

 

The Extra returned an Using filesort, implies the need to sort, this is the need to focus on optimization of the data that is found, mysql also need to be sorted in memory, you need to know the index itself is orderly , so in general should try to make ordering index, such as write like this.

 

mysql> explain select a from t where a > 99990 order by a;
+----+-------------+-------+-------+------------------+---------+---------+------+------+--------------------------+
| id | select_type | table | type  | possible_keys    | key     | key_len | ref  | rows | Extra                    |
+----+-------------+-------+-------+------------------+---------+---------+------+------+--------------------------+
|  1 | SIMPLE      | t     | range | a_index,ab_index | a_index | 5       | NULL |   10 | Using where; Using index |
+----+-------------+-------+-------+------------------+---------+---------+------+------+--------------------------+
1 row in set (0.00 sec)

 

We then create a composite index to see.

 

mysql> alter table t add index ab_index(a,b);
Query OK, 0 rows affected (0.19 sec)
Records: 0  Duplicates: 0  Warnings: 0

 

mysql> explain select * from t where a > 1000;
+----+-------------+-------+-------+------------------+----------+---------+------+-------+--------------------------+
| id | select_type | table | type  | possible_keys    | key      | key_len | ref  | rows  | Extra                    |
+----+-------------+-------+-------+------------------+----------+---------+------+-------+--------------------------+
|  1 | SIMPLE      | t     | range | a_index,ab_index | ab_index | 5       | NULL | 50166 | Using where; Using index |
+----+-------------+-------+-------+------------------+----------+---------+------+-------+--------------------------+
1 row in set (0.00 sec)

 

This sql just been mentioned above, there are, in the absence of creating a composite index, it is to take a full table scan, in fact, now is the use of a covering index , also eliminating the process back to the table, that is, on the (ab_index) Index You will be able to find the field you want to query.

 

这篇文章通过几个实例介绍了如何使用 explain 分析一条 sql 的执行计划,也提到了一些常见的索引优化,事实上还有更多的可能性,你也可以自己去写一个 sql ,然后使用 explain 分析,看看有哪些是可以被优化的。

 

这篇文章我断断续续写了有三四天了,本来准备了更多的例子,但每次都是写了一部分,思路也打乱了,好了,有问题欢迎在下面留言交流,文章对你有帮助,点个表示鼓励支持。

Guess you like

Origin blog.csdn.net/samll_snail/article/details/90765846