(C) database optimization of Python full-stack 9.MySQL senior -explain analyze SQL statements

First, the impact of several aspects of server performance

1. Hardware reason Conditions

  • Server hardware:
    memory size.
  • Server's operating system:
    different systems (Linux, Windows).
  • Database storage engine choices:
    choose different storage engines according to different needs.
  • Database configuration parameters:
    Different parameters can affect performance.
  • Database design and SQL statements:
    after the demolition of the table, a small table faster query efficiency.

2.SQL itself the cause performance degradation

  • Query badly written:
    sentence is too long, there are too many connections.
  • Failure Index:
    Indexing not spend.
  • Too many inquiries related join:
    There are too many connections, reduce performance.
  • And each server tuning parameters.

3.SQL statement load order

Hand-written SQL code sequence:

select distinct 
    <select _list>
from 
    <left_table>
join  <right_table> on <join_codition>
where
    <where_condition>
group by
    <group_by_list>
having
    <having_condition>
order by
    <order_by_condition>
limit <limit number>

Machine reading order of execution of the code:
Machine execution order
FIG.
SQL parsing

4.MySQL common bottlenecks

  • The CPU:
    the CPU generally occurs when the data into memory or reading data from the disk at the time of saturation;
  • IO:
    disk I / O bottlenecks occur when the load data is much larger than the memory capacity;
  • Server hardware performance bottleneck:
    memory, hard disk size.

Two, explain SQL analysis

1. Basic definitions

Use keywords can explain the analog optimizer execute SQL queries, so they know how to deal with MySQL is a SQL statement.

2.explain role:

  • Reading order table;
  • Type of operation of a data read operation;
  • Which indexes can be used;
  • Which indexes are actually used;
  • References between tables;
  • Each table of how many rows the query optimizer.

3.explain use

grammar:

explain + SQL语句;

E.g

explain select * from students;

print

+----+-------------+----------+------------+------+---------------+------+---------+------+------+----------+-------+
| id | select_type | table    | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra |
+----+-------------+----------+------------+------+---------------+------+---------+------+------+----------+-------+
|  1 | SIMPLE      | students | NULL       | ALL  | NULL          | NULL | NULL    | NULL |   27 |   100.00 | NULL  |
+----+-------------+----------+------------+------+---------------+------+---------+------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)

4.explain field interpretation

id:

Reading order table:
sequence number, contains a set of digital select query, clauses or select a sequence operation table query execution.
Two conditions:
(. 1) the same ID, execution order from top to bottom:
For example:

explain select test2.* from test1,test2,test3 where test1.id = test2.id and test1.id = test3.id;

print

+----+-------------+-------+------------+--------+---------------+---------+---------+---------------+------+----------+-------------+
| id | select_type | table | partitions | type   | possible_keys | key     | key_len | ref           | rows | filtered | Extra       |
+----+-------------+-------+------------+--------+---------------+---------+---------+---------------+------+----------+-------------+
|  1 | SIMPLE      | test1 | NULL       | index  | PRIMARY       | PRIMARY | 4       | NULL          |    1 |   100.00 | Using index |
|  1 | SIMPLE      | test2 | NULL       | eq_ref | PRIMARY       | PRIMARY | 4       | demo.test1.id |    1 |   100.00 | Using index |
|  1 | SIMPLE      | test3 | NULL       | eq_ref | PRIMARY       | PRIMARY | 4       | demo.test1.id |    1 |   100.00 | Using index |
+----+-------------+-------+------------+--------+---------------+---------+---------+---------------+------+----------+-------------+
3 rows in set, 1 warning (0.00 sec)                                                                                                   

Different (2) id, if a subquery, id is incremented sequence number, id value is larger the higher the priority, the first is performed:
for example:

 explain select test2.* from test2 where id = (select id from test1 where id = (select test3.id from test3 where test3.other_columns = ''));

print

+----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------------+
| id | select_type | table | partitions | type  | possible_keys | key     | key_len | ref   | rows | filtered | Extra       |
+----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------------+
|  1 | PRIMARY     | test2 | NULL       | const | PRIMARY       | PRIMARY | 4       | const |    1 |   100.00 | Using index |
|  2 | SUBQUERY    | test1 | NULL       | const | PRIMARY       | PRIMARY | 4       | const |    1 |   100.00 | Using index |
|  3 | SUBQUERY    | test3 | NULL       | ALL   | NULL          | NULL    | NULL    | NULL  |    1 |   100.00 | Using where |
+----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------------+
3 rows in set, 1 warning (0.00 sec)                                                                                                  

Obviously, the size of the id, the sequence table is read sequentially test3, test1, test2, to execute sub-queries, and then the parent query execution are sequentially performed from bottom to the top.
(. 3) different from the same id:
simultaneously performed when the id, the greater the first id not simultaneously be executed.

select_type:

Data read operation of the type of operation:
(. 1) Simple:
simply select query, the query does not include a subquery, or Union;
(2) Primary:
query if any complex comprising a sub-portion, the outermost query were marked, that is the last one loaded query;
(3) subquery:
contains the sub-query select list or where;
(4) of Union:
of Union is to query the results of two tables together.
If the second select appears after the union, were labeled union,

explain select * from test2 union select * from test4;

print

+----+--------------+------------+------------+-------+---------------+---------+---------+------+------+----------+-----------------+ 
| id | select_type  | table      | partitions | type  | possible_keys | key     | key_len | ref  | rows | filtered | Extra           | 
+----+--------------+------------+------------+-------+---------------+---------+---------+------+------+----------+-----------------+ 
|  1 | PRIMARY      | test2      | NULL       | index | NULL          | PRIMARY | 4       | NULL |    1 |   100.00 | Using index     | 
|  2 | UNION        | test4      | NULL       | index | NULL          | PRIMARY | 4       | NULL |    1 |   100.00 | Using index     | 
| NULL | UNION RESULT | <union1,2> | NULL       | ALL   | NULL          | NULL    | NULL    | NULL | NULL |     NULL | Using temporary 
+----+--------------+------------+------------+-------+---------------+---------+---------+------+------+----------+-----------------+ 
3 rows in set, 1 warning (0.01 sec)                                                                                                                                                                                                   

Only two tables of the same number of fields can be used.
(5) union result:
obtaining from the result of table union select.

table:

This line of display data about which tables are.

partitions:

Query partition access.

type:

The SQL execution efficiency, including ALL, index, range, ref, eq_ref, const, system, NULL and the like.
Order from best to worst is:
System> const> eq_ref> REF> Range> index> ALL.
(1) system:
table has only one row (equal to the system tables), which is a special case of type const, has little significance.
E.g

explain select * from mysql.db;

print

+----+-------------+-------+------------+---------+---------------+------+---------+------+------+----------+-------+
| id | select_type | table | partitions | type    | possible_keys | key  | key_len | ref  | rows | filtered | Extra |
+----+-------------+-------+------------+---------+---------------+------+---------+------+------+----------+-------+
|  1 | SIMPLE      | db    | NULL       | system  | NULL          | NULL | NULL    | NULL |    6 |   100.00 | NULL  |
+----+-------------+-------+------------+---------+---------------+------+---------+------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)                                                                                                                                                                                                                                                                                 

(2) const:
represented by the index once found, const for comparing the primary key, use less.
E.g

explain select * from test1 where id = 1;

print

+----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type  | possible_keys | key     | key_len | ref   | rows | filtered | Extra |
+----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
|  1 | SIMPLE      | test1 | NULL       | const | PRIMARY       | PRIMARY | 4       | const |    1 |   100.00 | NULL  |
+----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.01 sec)                                                                                                                                                                                                                                                                                

(3) eq_ref:
unique index scan, for each index key, the table is only one matching record
e.g.

explain select * from test1,test2 where test1.id = test2.id;

print

+----+-------------+-------+------------+--------+---------------+---------+---------+---------------+------+----------+-------------+
| id | select_type | table | partitions | type   | possible_keys | key     | key_len | ref           | rows | filtered | Extra       |
+----+-------------+-------+------------+--------+---------------+---------+---------+---------------+------+----------+-------------+
|  1 | SIMPLE      | test1 | NULL       | ALL    | PRIMARY       | NULL    | NULL    | NULL          |    1 |   100.00 | NULL        |
|  1 | SIMPLE      | test2 | NULL       | eq_ref | PRIMARY       | PRIMARY | 4       | demo.test1.id |    1 |   100.00 | Using index |
+----+-------------+-------+------------+--------+---------------+---------+---------+---------------+------+----------+-------------+
2 rows in set, 1 warning (0.01 sec)                                                                                                                                                                                                                                                                              

(4) ref:
non-unique index scanning, returns all rows matching a separate value, an index that is essentially accessed, it returns all rows match a separate value
e.g.

create index idx_col1_col2 on test3(col1,col2);
explain select * from test3 where col1 = 'test';

print

+----+-------------+-------+------------+------+---------------+---------------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key           | key_len | ref   | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+---------------+---------+-------+------+----------+-------+
|  1 | SIMPLE      | test3 | NULL       | ref  | idx_col1_col2 | idx_col1_col2 | 93      | const |    1 |   100.00 | NULL  |
+----+-------------+-------+------------+------+---------------+---------------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)                                                                                                                                                                                                                                                                             

(5) range:
retrieve only to the line given range, using an index to select the rows, where the statement contains between ... and ..., that is, when the range in ... conditions, generally where clause field is possible only if the primary key range .
E.g

explain select * from test1 where id between 1 and 10;

print

+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type  | possible_keys | key     | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | test1 | NULL       | range | PRIMARY       | PRIMARY | 4       | NULL |    1 |   100.00 | Using where |
+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)                                                                                                                                                                                                                                                                            

(. 6) index:
Full Scan Index, index differs only ALL is traversing the index tree index type.
E.g

explain select id from test1;

print

+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+-------------+ 
| id | select_type | table | partitions | type  | possible_keys | key     | key_len | ref  | rows | filtered | Extra       | 
+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+-------------+ 
|  1 | SIMPLE      | test1 | NULL       | index | NULL          | PRIMARY | 4       | NULL |    1 |   100.00 | Using index | 
+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+-------------+ 
1 row in set, 1 warning (0.01 sec)                                                                                                                                                                                                                                                                                                                                                                    

(7) ALL:
traverse the whole table to find matching rows.
E.g

explain select * from test1;

print

+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+
|  1 | SIMPLE      | test1 | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    1 |   100.00 | NULL  |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)                                                                                                                                                                                                                                                                                                                                                                  

possible_keys:

Shows the possible application of the index in this table, one or more.

key:

Index actually used, if it is null, then do not use the index.
E.g

explain select col1,col2 from test3;

print

+----+-------------+-------+------------+-------+---------------+---------------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type  | possible_keys | key           | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-------+------------+-------+---------------+---------------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | test3 | NULL       | index | NULL          | idx_col1_col2 | 186     | NULL |    1 |   100.00 | Using index |
+----+-------------+-------+------------+-------+---------------+---------------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.01 sec)                                                                                                                                                                                                                                                                                                                                                                                                                                                                 

Covering indexes, query column built to be covered by the index, columns col1 above example query, the index is created idx_col1_col2 col2 coverage.
If the query uses the coverage index, the index appears only in the key list.

key_len:

Indicates the number of bytes used in the index, the index can be used in the query length is calculated by the column.
Without loss of accuracy, a length as short as possible.
The maximum possible length values of the index fields displayed key_len, not the actual length , i.e., is calculated on the basis key_len table definition, it is not retrieved by the table.
Calculating the length of the index:

varchr(n)变长字段且允许NULL:
n*(Character Set:utf8=3,gbk=2,latin1=1)+1(NULL)+2(变长字段)
varchr(n)变长字段且不允许NULL:
n*(Character Set:utf8=3,gbk=2,latin1=1)+2(变长字段)
char(n)固定字段且允许NULL:
n*(Character Set:utf8=3,gbk=2,latin1=1)+1(NULL)
char(n)固定字段且不允许NULL:
n*(Character Set:utf8=3,gbk=2,latin1=1)

In the embodiment, the character set to utf8 3, allowing a non-empty, a variable length 2, and has two fields, so there
key_len = (30 × 3 + 1 + 2) × 2 = 186.

ref:

Display index which column is used to.
Some examples of the results table reading order id, ref column value of 2,3 demo.test1.id, test1 represents demo database table id field is used.

rows:

According to the statistics table and choose the index case, a rough estimate of the number of lines needed to find records to be read.
Figure
Here Insert Picture Description

Extra:

包含不适合在其他列中显示但十分重要的额外信息。
(1)Using filesort:
说明mysql会对数据使用一个外部的索引排序,而不是按照表内的索引顺序进行读取,MySQL中无法利用索引完成的排序操作称为"文件排序",说明需要进行优化。
例如

drop index idx_col1_col2 from test3;
create index idx_col1_col2_col3 on test3(col1,col2,col3);
explain select * from test3 where col1 = 'test' order by col3;

打印

+----+-------------+-------+------------+------+--------------------+--------------------+---------+-------+------+----------+---------------------------------------+
| id | select_type | table | partitions | type | possible_keys      | key                | key_len | ref   | rows | filtered | Extra                                 |
+----+-------------+-------+------------+------+--------------------+--------------------+---------+-------+------+----------+---------------------------------------+
|  1 | SIMPLE      | test3 | NULL       | ref  | idx_col1_col2_col3 | idx_col1_col2_col3 | 93      | const |    1 |   100.00 | Using index condition; Using filesort |
+----+-------------+-------+------------+------+--------------------+--------------------+---------+-------+------+----------+---------------------------------------+
1 row in set, 1 warning (0.00 sec)                                                                                                                                                                                                                                                                                                                                                                                                                                                                 

显然,此时出现了filesort,需要进行优化。
例如

explain select * from test3 where col1 = 'test' order by col2,col3;

打印

+----+-------------+-------+------------+------+--------------------+--------------------+---------+-------+------+----------+-----------------------+
| id | select_type | table | partitions | type | possible_keys      | key                | key_len | ref   | rows | filtered | Extra                 |
+----+-------------+-------+------------+------+--------------------+--------------------+---------+-------+------+----------+-----------------------+
|  1 | SIMPLE      | test3 | NULL       | ref  | idx_col1_col2_col3 | idx_col1_col2_col3 | 93      | const |    1 |   100.00 | Using index condition |
+----+-------------+-------+------------+------+--------------------+--------------------+---------+-------+------+----------+-----------------------+
1 row in set, 1 warning (0.01 sec)                                                                                                                                                                                                                                                                                                                                                                                                                                                                 

此时不再有filesort。
(2)Using temporary:
使用临时表保存中间结果,MySQL在对查询结果排序时使用临时表,一般出现在使用了order by、group by的时候,性能极差。
例如

explain select * from test3 where col1 in ('te','st') group by col2;

打印

+----+-------------+-------+------------+------+--------------------+------+---------+------+------+----------+----------------------------------------------+
| id | select_type | table | partitions | type | possible_keys      | key  | key_len | ref  | rows | filtered | Extra                                        |
+----+-------------+-------+------------+------+--------------------+------+---------+------+------+----------+----------------------------------------------+
|  1 | SIMPLE      | test3 | NULL       | ALL  | idx_col1_col2_col3 | NULL | NULL    | NULL |    1 |   100.00 | Using where; Using temporary; Using filesort |
+----+-------------+-------+------------+------+--------------------+------+---------+------+------+----------+----------------------------------------------+                                                                                                                                                                                                                                                                                                                                                                                                                                                                
1 row in set, 1 warning (0.01 sec)

显然,同时出现了filesort、temporary,需要优化。
例如

explain select * from test3 where col1 in ('te','st') group by col1,col2;

打印

+----+-------------+-------+------------+-------+--------------------+--------------------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type  | possible_keys      | key                | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-------+------------+-------+--------------------+--------------------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | test3 | NULL       | index | idx_col1_col2_col3 | idx_col1_col2_col3 | 279     | NULL |    1 |   100.00 | Using where |
+----+-------------+-------+------------+-------+--------------------+--------------------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.01 sec)                                                                                                                                                                                                                                                                                                                                                                                                                           

此时filesort、temporary均消失,我们应该尽量按照建立索引的顺序进行分组、排序。
(3)Using index:
使用了索引,避免了全表扫描。
(4)Using where:
使用了where过滤。
(5)Using join buffer:
使用了连接缓存。
(6)impossible where:
不可能的条件,where子句的值总是false。
例如

explain select * from test3 where id = 1 and id = 2;

打印

+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+------------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra            |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+------------------+
|  1 | SIMPLE      | NULL  | NULL       | NULL | NULL          | NULL | NULL    | NULL | NULL |     NULL | Impossible WHERE |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+------------------+
1 row in set, 1 warning (0.01 sec)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     

Xiao Bian then fight, then withdraw like this one!
欢迎大家加入群聊【python知识交流分享群】,进行技术交流:https://jq.qq.com/?_wv=1027&k=5m5AduZ
Here Insert Picture Description

Published 51 original articles · won praise 184 · views 30000 +

Guess you like

Origin blog.csdn.net/CUFEECR/article/details/103566353