Mysql优化补充

2020-03-04  本文已影响0人  笨鸡

1.查看sql执行频率

mysql> show status like 'Com_______';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Com_binlog    | 0     |
| Com_commit    | 0     |
| Com_delete    | 0     |
| Com_insert    | 0     |
| Com_repair    | 0     |
| Com_revoke    | 0     |
| Com_select    | 19    |
| Com_signal    | 0     |
| Com_update    | 0     |
| Com_xa_end    | 0     |
+---------------+-------+
10 rows in set (0.00 sec)
mysql> show global status like 'Com_______';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Com_binlog    | 0     |
| Com_commit    | 0     |
| Com_delete    | 0     |
| Com_insert    | 12    |
| Com_repair    | 0     |
| Com_revoke    | 0     |
| Com_select    | 519   |
| Com_signal    | 0     |
| Com_update    | 13    |
| Com_xa_end    | 0     |
+---------------+-------+
10 rows in set (0.00 sec)
mysql> show global status like 'Innodb_rows_%';
+----------------------+-------+
| Variable_name        | Value |
+----------------------+-------+
| Innodb_rows_deleted  | 0     |
| Innodb_rows_inserted | 1401  |
| Innodb_rows_read     | 1990  |
| Innodb_rows_updated  | 24    |
+----------------------+-------+
4 rows in set (0.00 sec)

2.定位低效率执行SQL

mysql> show processlist;
+-----+------+-----------------+------------+---------+------+----------+------------------+
| Id  | User | Host            | db         | Command | Time | State    | Info             |
+-----+------+-----------------+------------+---------+------+----------+------------------+
|   2 | root | localhost:54845 | mysql_test | Sleep   | 2990 |          | NULL             |
|   3 | root | localhost:54857 | mysql_test | Sleep   | 2990 |          | NULL             |
| 144 | root | localhost:65226 | mysql_test | Query   |    0 | starting | show processlist |
+-----+------+-----------------+------------+---------+------+----------+------------------+
3 rows in set (0.00 sec)

3.执行计划

mysql> explain select * from t_class;
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------+
| id | select_type | table   | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra |
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------+
|  1 | SIMPLE      | t_class | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 1000 |   100.00 | NULL  |
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)
mysql> explain select * from user u, role r, user_role ur where u.id=ur.user_id and r.id=ur.role_id\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: r
   partitions: NULL
         type: ALL
possible_keys: PRIMARY
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 2
     filtered: 100.00
        Extra: NULL
*************************** 2. row ***************************
           id: 1
  select_type: SIMPLE
        table: ur
   partitions: NULL
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 3
     filtered: 33.33
        Extra: Using where; Using join buffer (Block Nested Loop)
*************************** 3. row ***************************
           id: 1
  select_type: SIMPLE
        table: u
   partitions: NULL
         type: eq_ref
possible_keys: PRIMARY
          key: PRIMARY
      key_len: 4
          ref: boot_mybatis_plus.ur.user_id
         rows: 1
     filtered: 100.00
        Extra: NULL
3 rows in set, 1 warning (0.00 sec)


mysql> explain select * from user where id = (select user_id from user_role where role_id=1)\G
*************************** 1. row ***************************
           id: 1
  select_type: PRIMARY
        table: user
   partitions: NULL
         type: const
possible_keys: PRIMARY
          key: PRIMARY
      key_len: 4
          ref: const
         rows: 1
     filtered: 100.00
        Extra: NULL
*************************** 2. row ***************************
           id: 2
  select_type: SUBQUERY
        table: user_role
   partitions: NULL
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 3
     filtered: 33.33
        Extra: Using where
2 rows in set, 1 warning (0.00 sec)


mysql> explain select * from role r,(select * from user_role where user_id=1) a where r.id=a.role_id\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: user_role
   partitions: NULL
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 3
     filtered: 33.33
        Extra: Using where
*************************** 2. row ***************************
           id: 1
  select_type: SIMPLE
        table: r
   partitions: NULL
         type: eq_ref
possible_keys: PRIMARY
          key: PRIMARY
      key_len: 4
          ref: boot_mybatis_plus.user_role.role_id
         rows: 1
     filtered: 100.00
        Extra: NULL
2 rows in set, 1 warning (0.00 sec)
select_type 说明
SIMPLE 普通
PRIMARY 子查询最外层
SUBQUERY 子查询内层
DERIVED 子查询在from块
UNION union操作内层
UNION RESULT union操作结果
type 说明
NULL MYSQL不访问任何表,索引,直接返回结果
system 表只有一行记录,const特例
const 索引一次找到,主键或唯一索引
eq_ref 类似ref,主键或唯一索引
ref 非唯一性索引扫描
range 检索给定返回的行
index 遍历了索引树
all 全数据扫描

优化至少到range,最好到ref

key 说明
possible_keys 显示可能应用在这张表的索引
key 实际使用的索引,如果为NULL,则没有使用索引
key_len 索引中使用字节数,越短越好

4.Query Profiler

mysql> select @@have_profiling;
+------------------+
| @@have_profiling |
+------------------+
| YES              |
+------------------+
1 row in set, 1 warning (0.00 sec)

mysql> select @@profiling;
+-------------+
| @@profiling |
+-------------+
|           0 |
+-------------+
1 row in set, 1 warning (0.00 sec)

mysql> set profiling=1;
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> select @@profiling;
+-------------+
| @@profiling |
+-------------+
|           1 |
+-------------+
1 row in set, 1 warning (0.00 sec)

mysql> show profiles;
+----------+------------+-------------------------+
| Query_ID | Duration   | Query                   |
+----------+------------+-------------------------+
|        1 | 0.38714850 | select * from t_student |
+----------+------------+-------------------------+
1 row in set, 1 warning (0.00 sec)

mysql> show profile for query 1;
+--------------------------------+----------+
| Status                         | Duration |
+--------------------------------+----------+
| starting                       | 0.000023 |
| Waiting for query cache lock   | 0.000006 |
| starting                       | 0.000001 |
| checking query cache for query | 0.000028 |
| checking permissions           | 0.000014 |
| checking permissions           | 0.000002 |
| Opening tables                 | 0.000010 |
| init                           | 0.000025 |
| System lock                    | 0.000007 |
| optimizing                     | 0.000002 |
| statistics                     | 0.000024 |
| preparing                      | 0.000011 |
| executing                      | 0.000002 |
| Sending data                   | 0.386937 |
| end                            | 0.000008 |
| query end                      | 0.000005 |
| closing tables                 | 0.000006 |
| freeing items                  | 0.000015 |
| cleaning up                    | 0.000025 |
+--------------------------------+----------+
19 rows in set, 1 warning (0.00 sec)


# show profile all(cpu) for query 1;

mysql> show profile cpu for query 1;
+--------------------------------+----------+----------+------------+
| Status                         | Duration | CPU_user | CPU_system |
+--------------------------------+----------+----------+------------+
| starting                       | 0.000023 | 0.000000 |   0.000000 |
| Waiting for query cache lock   | 0.000006 | 0.000000 |   0.000000 |
| starting                       | 0.000001 | 0.000000 |   0.000000 |
| checking query cache for query | 0.000028 | 0.000000 |   0.000000 |
| checking permissions           | 0.000014 | 0.000000 |   0.000000 |
| checking permissions           | 0.000002 | 0.000000 |   0.000000 |
| Opening tables                 | 0.000010 | 0.000000 |   0.000000 |
| init                           | 0.000025 | 0.000000 |   0.000000 |
| System lock                    | 0.000007 | 0.000000 |   0.000000 |
| optimizing                     | 0.000002 | 0.000000 |   0.000000 |
| statistics                     | 0.000024 | 0.000000 |   0.000000 |
| preparing                      | 0.000011 | 0.000000 |   0.000000 |
| executing                      | 0.000002 | 0.000000 |   0.000000 |
| Sending data                   | 0.386937 | 0.359375 |   0.031250 |
| end                            | 0.000008 | 0.000000 |   0.000000 |
| query end                      | 0.000005 | 0.000000 |   0.000000 |
| closing tables                 | 0.000006 | 0.000000 |   0.000000 |
| freeing items                  | 0.000015 | 0.000000 |   0.000000 |
| cleaning up                    | 0.000025 | 0.000000 |   0.000000 |
+--------------------------------+----------+----------+------------+
19 rows in set, 1 warning (0.00 sec)

5.trace

mysql> set optimizer_trace="enabled=on",end_markers_in_json=on;
Query OK, 0 rows affected (0.00 sec)

mysql> set optimizer_trace_max_mem_size=1000000;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from t_student where id <= 4;
+----+------------+-----------+--------+-------+--------------------------------------+----------+
| id | first_name | last_name | gender | user  | password                             | class_id |
+----+------------+-----------+--------+-------+--------------------------------------+----------+
|  1 | e5bec      | 485e4     |      1 | NULL  | b4a7029f-4dd2-45ef-a58f-da85db58da8a |      875 |
|  2 | 8cd0a      | 35262     |      2 | NULL  | d236875f-ff7f-4f2c-a025-9e3bb00b48cd |      360 |
|  3 | d7013      | 69586     |      1 | 3dd-c | d45a9d11-5241-4096-9925-5e939443c538 |      906 |
|  4 | d4c6d      | 57f2a     |      2 | cff-4 | e272e138-4342-4712-b85a-fa011e494165 |      979 |
+----+------------+-----------+--------+-------+--------------------------------------+----------+
4 rows in set (0.00 sec)

mysql> select * from information_schema.optimizer_trace\G
*************************** 1. row ***************************
                            QUERY: select * from t_student where id <= 4
                            TRACE: {
  "steps": [
    {
      "join_preparation": {
        "select#": 1,
        "steps": [
          ...
    {
      "join_execution": {
        "select#": 1,
        "steps": [
        ] /* steps */
      } /* join_execution */
    }
  ] /* steps */
}
MISSING_BYTES_BEYOND_MAX_MEM_SIZE: 0
          INSUFFICIENT_PRIVILEGES: 0
1 row in set (0.00 sec)

6.索引

// 误区1    (走索引,但只走一半)
select * from user where name = 'a' and address = 'beijing';   走name
// 误区2  (where 条件只要包含就能生效)
select * from user where age = 20 and address = 'bj' and name = 'a';   走索引(name, age, address)
select * from user where age > 20 and address = 'bj' and name = 'a';   走索引(name,age)
select * from user where age - 1 > 20 and name = 'a';    走索引(name)
select count(*) from user where month(create_time)=7;    失效
// 优化
select count(*) from user where (t_modified >= '2016-7-1' and t_modified<'2016-8-1') 
or (t_modified >= '2017-7-1' and t_modified<'2017-8-1');
select * from user where name = 'a' and sex = 1;
// 优化
select * from user where name = 'a' and sex = '1';
select * from user where name = 'a';   Using index condition
select name, age, address from user where name = 'a'    Using where;Using index
select name, age, address, password from user where name = 'a'   Using index condition
select * from user where name = '%李%';
// 用主键或复合索引来覆盖索引优化
select id, name, age, address from user where name = '%李%';
// 索引未全覆盖会回表查询
select id, name, age, address, password from user where name = '%李%';
mysql> show status like 'handler_read%';
+-----------------------+---------+
| Variable_name         | Value   |
+-----------------------+---------+
| Handler_read_first    | 7       |
| Handler_read_key      | 5       |
| Handler_read_last     | 0       |
| Handler_read_next     | 8       |
| Handler_read_prev     | 0       |
| Handler_read_rnd      | 0       |
| Handler_read_rnd_next | 1400074 |
+-----------------------+---------+
7 rows in set (0.00 sec)
上一篇 下一篇

猜你喜欢

热点阅读