第09章 性能分析工具的使用【2.索引及调优篇】【MySQL高级】2

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
云数据库 RDS PostgreSQL,高可用系列 2核4GB
简介: 第09章 性能分析工具的使用【2.索引及调优篇】【MySQL高级】2

4.3 案例演示

步骤1. 建表

CREATE TABLE `student` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`stuno` INT NOT NULL ,
`name` VARCHAR(20) DEFAULT NULL,
`age` INT(3) DEFAULT NULL,
`classId` INT(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

步骤2:设置参数log_bin_trust_function_creators

创建函数,假如报错:This function has none of DETERMINISTIC…

命令开启:允许创建函数设置

set global log_bin_trust_function_creators=1; # 不加global只是当前窗口有效。

步骤3:创建函数

随机产生字符串:(同上一章)

DELIMITER //
CREATE FUNCTION rand_string(n INT)
RETURNS VARCHAR(255) #该函数会返回一个字符串
BEGIN
DECLARE chars_str VARCHAR(100) DEFAULT
'abcdefghijklmnopqrstuvwxyzABCDEFJHIJKLMNOPQRSTUVWXYZ';
DECLARE return_str VARCHAR(255) DEFAULT '';
DECLARE i INT DEFAULT 0;
WHILE i < n DO
SET return_str =CONCAT(return_str,SUBSTRING(chars_str,FLOOR(1+RAND()*52),1));
SET i = i + 1;
END WHILE;
RETURN return_str;
END //
DELIMITER ;
#测试
SELECT rand_string(10);
DELIMITER //
CREATE FUNCTION rand_num (from_num INT ,to_num INT) RETURNS INT(11)
BEGIN
DECLARE i INT DEFAULT 0;
SET i = FLOOR(from_num +RAND()*(to_num - from_num+1)) ;
RETURN i;
END //
DELIMITER ;
#测试:
SELECT rand_num(10,100);
/*
+------------------+
| rand_num(10,100) |
+------------------+
|               23 |
+------------------+
*/

步骤4:创建存储过程

DELIMITER //
CREATE PROCEDURE insert_stu1( START INT , max_num INT )
BEGIN
DECLARE i INT DEFAULT 0;
SET autocommit = 0; #设置手动提交事务
REPEAT #循环
SET i = i + 1; #赋值
INSERT INTO student (stuno, NAME ,age ,classId ) VALUES
((START+i),rand_string(6),rand_num(10,100),rand_num(10,1000));
UNTIL i = max_num
END REPEAT;
COMMIT; #提交事务
END //
DELIMITER ;

步骤5:调用存储过程

#调用刚刚写好的函数, 4000000条记录,从100001号开始
CALL insert_stu1(100001,4000000);
mysql> SELECT COUNT(*) FROM student;
+----------+
| COUNT(*) |
+----------+
|  4000000 |
+----------+
1 row in set (0.70 sec)

4.4 测试及分析

1. 测试

SELECT * FROM student WHERE stuno = 3455655;
/*
+---------+---------+--------+------+---------+
| id      | stuno   | name   | age  | classId |
+---------+---------+--------+------+---------+
| 3355654 | 3455655 | IHnqPe |   14 |     943 |
+---------+---------+--------+------+---------+
1 row in set (1.33 sec)
*/
SELECT * FROM student WHERE name = 'IHnqPe ';
/*
+---------+---------+--------+------+---------+
| id      | stuno   | name   | age  | classId |
+---------+---------+--------+------+---------+
| 2264898 | 2364899 | IHnqPe |   14 |     968 |
| 2802437 | 2902438 | IHnqPe |   13 |     933 |
| 2947412 | 3047413 | IHnqPe |   13 |     929 |
| 3355654 | 3455655 | IHnqPe |   14 |     943 |
| 3432555 | 3532556 | IhNqpE |   15 |     507 |
+---------+---------+--------+------+---------+
5 rows in set (1.43 sec)
*/

从上面的结果可以看出来,查询学生编号为“3455655”的学生信息花费时间为1.33 秒。查询学生姓名为“IHnqPe”的学生信息花费时间为1.43 秒。已经达到了秒的数量级,说明目前查询效率是比较低的,下面我们分析一下原因:

2. 分析

show status like 'slow_queries';
/*
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Slow_queries  | 2     |
+---------------+-------+
*/

补充说明:



除了上述变量,控制慢查询日志的还有一个系统变量: min_examined_row_limit。这个变量的意思是,查询扫描过的最少记录数。这个变晕和查询执行时间,共同组成了判别一个查询是否是慢查询的条件。如果查询扫描过的记录数大于等于这个变量的值,并且查询执行时间超过long_query_time的值,那么,这个查询就被记录到慢查询日志中;反之,则不被记录到慢查询日志中。



mysql> show variables like ‘min%’;

/*

±-----------------------±------+

| Variable_name | Value |

±-----------------------±------+

| min_examined_row_limit | 0 |

±-----------------------±------+

1 row in set (0.02 sec)

*/



这个值默认是0。与long_query_time=10合在一起,表示只要查询的执行时间超过10秒钟,哪怕一个记录也没有扫描过,都要被记录到慢查询日志中。也可以根据需要,通过修“my.ini"文件,来修改查询时长,或者通过SET指令,用SQL语句修改“min_examined_row_limit"的值。

4.5 慢查询日志分析工具:mysqldumpslow

在生产环境中,如果要手工分析日志,查找、分析SQL,显然是个体力活,MySQL提供了日志分析工具mysqldumpslow

查看mysqldumpslow的帮助信息

#注意:下面语句不是在mysql>下执行,而要在根目录下执行
[root@centos7-mysql-1 ~]# mysqldumpslow --help
/*
Usage: mysqldumpslow [ OPTS... ] [ LOGS... ]
Parse and summarize the MySQL slow query log. Options are
  --verbose    verbose
  --debug      debug
  --help       write this text to standard output
  -v           verbose
  -d           debug
  -s ORDER     what to sort by (al, at, ar, c, l, r, t), 'at' is default
                al: average lock time
                ar: average rows sent
                at: average query time
                 c: count
                 l: lock time
                 r: rows sent
                 t: query time  
  -r           reverse the sort order (largest last instead of first)
  -t NUM       just show the top n queries
  -a           don't abstract all numbers to N and strings to 'S'
  -n NUM       abstract numbers with at least n digits within names
  -g PATTERN   grep: only consider stmts that include this string
  -h HOSTNAME  hostname of db server for *-slow.log filename (can be wildcard),
               default is '*', i.e. match all
  -i NAME      name of server instance (if using mysql.server startup script)
  -l           don't subtract lock time from total time
*/

mysqldumpslow 命令的具体参数如下:

-a: 不将数字抽象成N,字符串抽象成S

-s: 是表示按照何种方式排序:


c: 访问次数

l: 锁定时间

r: 返回记录

t: 查询时间

al:平均锁定时间

ar:平均返回记录数

at:平均查询时间 (默认方式)

ac:平均查询次数

-t :即为返回前面多少条的数据;

-g: 后边搭配一个正则匹配模式,大小写不敏感的


下面演示如何得到慢查询:

首先找到慢查询文件在哪个目录下:

#首先找到慢查询文件在哪个目录下:
[root@centos7-mysql-1 ~]# cd /var/lib/mysql
[root@centos7-mysql-1 mysql]# ll
#运行结构可知目录为LSLNO1-slow.log
/*
总用量 902900
drwxr-x---. 2 mysql mysql        67 8月   3 18:23 atguigudb1
-rw-r-----. 1 mysql mysql        56 7月  25 19:53 auto.cnf
-rw-r-----. 1 mysql mysql       498 7月  25 20:34 binlog.000001
-rw-r-----. 1 mysql mysql      1400 7月  27 18:19 binlog.000002
-rw-r-----. 1 mysql mysql      7004 7月  28 20:02 binlog.000003
-rw-r-----. 1 mysql mysql 647264629 8月   3 18:33 binlog.000004
-rw-r-----. 1 mysql mysql        64 7月  29 10:00 binlog.index
-rw-------. 1 mysql mysql      1680 7月  25 19:53 ca-key.pem
-rw-r--r--. 1 mysql mysql      1112 7月  25 19:53 ca.pem
-rw-r-----. 1 mysql mysql       901 8月   3 18:43 centos7-mysql-1-slow.log
-rw-r--r--. 1 mysql mysql      1112 7月  25 19:53 client-cert.pem
-rw-------. 1 mysql mysql      1676 7月  25 19:53 client-key.pem
drwxr-x---. 2 mysql mysql      4096 7月  31 11:15 dbtest1
drwxr-x---. 2 mysql mysql       242 8月   3 13:21 dbtest2
-rw-r-----. 1 mysql mysql    196608 8月   3 18:33 #ib_16384_0.dblwr
-rw-r-----. 1 mysql mysql   8585216 8月   3 14:18 #ib_16384_1.dblwr
-rw-r-----. 1 mysql mysql      3795 7月  28 20:02 ib_buffer_pool
-rw-r-----. 1 mysql mysql  12582912 8月   3 18:32 ibdata1
-rw-r-----. 1 mysql mysql  50331648 8月   3 18:33 ib_logfile0
-rw-r-----. 1 mysql mysql  50331648 8月   3 18:33 ib_logfile1
-rw-r-----. 1 mysql mysql  12582912 7月  29 10:00 ibtmp1
drwxr-x---. 2 mysql mysql       187 7月  29 10:00 #innodb_temp
drwxr-x---. 2 mysql mysql       143 7月  25 19:53 mysql
-rw-r-----. 1 mysql mysql  25165824 8月   3 18:33 mysql.ibd
srwxrwxrwx. 1 mysql mysql         0 7月  29 10:00 mysql.sock
-rw-------. 1 mysql mysql         5 7月  29 10:00 mysql.sock.lock
drwxr-x---. 2 mysql mysql      8192 7月  25 19:53 performance_schema
-rw-------. 1 mysql mysql      1680 7月  25 19:53 private_key.pem
-rw-r--r--. 1 mysql mysql       452 7月  25 19:53 public_key.pem
-rw-r--r--. 1 mysql mysql      1112 7月  25 19:53 server-cert.pem
-rw-------. 1 mysql mysql      1676 7月  25 19:53 server-key.pem
drwxr-x---. 2 mysql mysql        28 7月  25 19:53 sys
-rw-r-----. 1 mysql mysql  83886080 8月   3 18:33 undo_001
-rw-r-----. 1 mysql mysql  33554432 8月   3 18:32 undo_002
*/

举例:我们想要按照查询时间排序,查看前五条 SQL 语句,这样写即可:

#查看前五条 SQL 语句
[root@centos7-mysql-1 mysql]# mysqldumpslow -s t -t 5 /var/lib/mysql/centos7-mysql-1-slow.log
/*查询结果
Count: 1  Time=251.55s (251s)  Lock=0.00s (0s)  Rows=0.0 (0), root[root]@[192.168.253.134]
  CALL insert_stu1(N,N)
Count: 1  Time=1.43s (1s)  Lock=0.00s (0s)  Rows=5.0 (5), root[root]@localhost
  SELECT * FROM student WHERE name = 'S'
Count: 1  Time=1.29s (1s)  Lock=0.03s (0s)  Rows=1.0 (1), root[root]@localhost
  SELECT * FROM student WHERE stuno = N
Died at /usr/bin/mysqldumpslow line 162, <> chunk 3.
*/

不想替换S、N 用-a 花费时间降序排列

[root@centos7-mysql-1 mysql]# mysqldumpslow -a -s t -t 5 /var/lib/mysql/centos7-mysql-1-slow.log
Reading mysql slow query log from /var/lib/mysql/centos7-mysql-1-slow.log
Count: 1  Time=251.55s (251s)  Lock=0.00s (0s)  Rows=0.0 (0), root[root]@[192.168.253.134]
  CALL insert_stu1(100001,4000000)
Count: 1  Time=1.43s (1s)  Lock=0.00s (0s)  Rows=5.0 (5), root[root]@localhost
  SELECT * FROM student WHERE name = 'IHnqPe '
Count: 1  Time=1.29s (1s)  Lock=0.03s (0s)  Rows=1.0 (1), root[root]@localhost
  SELECT * FROM student WHERE stuno = 3455655
Died at /usr/bin/mysqldumpslow line 162, <> chunk 3.

工作常用参考:

#得到返回记录集最多的10个SQL
mysqldumpslow -s r -t 10 /var/lib/mysql/atguigu-slow.log
#得到访问次数最多的10个SQL
mysqldumpslow -s c -t 10 /var/lib/mysql/atguigu-slow.log
#得到按照时间排序的前10条里面含有左连接的查询语句
mysqldumpslow -s t -t 10 -g "left join" /var/lib/mysql/atguigu-slow.log
#另外建议在使用这些命令时结合 | 和more 使用 ,否则有可能出现爆屏情况
mysqldumpslow -s r -t 10 /var/lib/mysql/atguigu-slow.log | more

4.6 关闭慢查询日志

MySQL服务器停止慢查询日志功能有两种方法:

方式1:永久性方式

[mysqld]
slow_query_log=OFF

或者,把slow_query_log一项注释掉 或 删除

[mysqld]
#slow_query_log =OFF

重启MySQL服务,执行如下语句查询慢日志功能。

SHOW VARIABLES LIKE ‘%slow%’; #查询慢查询日志所在目录
SHOW VARIABLES LIKE ‘%long_query_time%’; #查询超时时长

可以看到,MySQL系统中的慢查询日志是关闭的。

方式2:临时性方式

使用SET语句来设置。

(1)停止MySQL慢查询日志功能,具体SQL语句如下

SET GLOBAL slow_query_log=off;
SHOW VARIABLES LIKE '%slow%';
/*
+---------------------------+--------------------------------+
| Variable_name             | Value                          |
+---------------------------+--------------------------------+
| log_slow_admin_statements | OFF                            |
| log_slow_extra            | OFF                            |
| log_slow_slave_statements | OFF                            |
| slow_launch_time          | 2                              |
| slow_query_log            | OFF                            |
| slow_query_log_file       | /var/lib/mysql/LSLNO1-slow.log |
+---------------------------+--------------------------------+
*/
#以及
SHOW VARIABLES LIKE '%long_query_time%';
/*
+-----------------+----------+
| Variable_name   | Value    |
+-----------------+----------+
| long_query_time | 1.000000 |
+-----------------+----------+
*/

(2)重启MySQL服务,使用SHOW语句查询慢查询日志功能信息,具体SQL语句如下

#在根目录下重启服务
[root@centos7-mysql-1 mysql]# systemctl restart mysqld
mysql> SHOW VARIABLES LIKE '%long_query_time%';
/*
重启后阈值恢复默认值10
+-----------------+-----------+
| Variable_name   | Value     |
+-----------------+-----------+
| long_query_time | 10.000000 |
+-----------------+-----------+
*/

4.7 删除慢查询日志

查询并调优完后该日志没有用了,可以将其删除

使用SHOW语句显示慢查询日志信息,具体SQL语句如下

show variables like 'slow_query_log%';
/*
+---------------------+-----------------------------------------+
| Variable_name       | Value                                   |
+---------------------+-----------------------------------------+
| slow_query_log      | OFF                                     |
| slow_query_log_file | /var/lib/mysql/centos7-mysql-1-slow.log |
+---------------------+-----------------------------------------+
2 rows in set (0.00 sec)
*/

从执行结果可以看出,慢查询日志的目录默认为MySQL的数据目录,在该目录下手动删除慢查询日志文件即可

[root@LSLNO1 mysql]# rm centos7-mysql-1-slow.log
rm:是否删除普通文件 "LSLNO1-slow.log"?y

使用命令mysqladmin flush-logs 来重新生成查询日志文件,具体命令如下,执行完毕会在数据目录下重新生成慢查询日志文件

mysqladmin -uroot -p flush-logs slow
# 在打开的条件下,执行上面的语句,才可以看见重置的日志文件
SET GLOBAL slow_query_log=on;

提示:

慢查询日志都是使用mysqladmin flush-logs命令来删除重建的。使用时一定要注意,一旦执行了这个命令,慢查询日志都只存在新的日志文件中,如果需要旧的查询日志,就必须享先备份。

5. 查看 SQL 执行成本:SHOW PROFILE

show profile在《逻辑架构》章节中讲过,这里作为复习。

Show Profile是MySQL提供的可以用来分析当前会话中SQL都做了什么、执行的资源消耗情况的工具,可用于sql调优的测量。默认情况下处于关闭状态,并保存最近15次的运行结果。

可以在会话级别开启这个功能

show variables like 'profiling';
/*
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| profiling     | OFF   |
+---------------+-------+
*/

通过设profiling='ON’来开启show profile :

set profiling = 'ON';

show profile使用演示:

use atguigudb;
select * from student where stuno =343455;
--
select * from student where name = 'vyituS';
--
show profiles;
/*
+----------+------------+---------------------------------------------+
| Query_ID | Duration   | Query                                       |
+----------+------------+---------------------------------------------+
|        1 | 0.00174700 | show variables like 'profiling'             |
|        2 | 1.52700950 | select * from student where stuno =343455   |
|        3 | 1.20279475 | select * from student where name = 'vyituS' |
+----------+------------+---------------------------------------------+
3 rows in set, 1 warning (0.00 sec)
*/
show profile;
/*
+--------------------------------+----------+
| Status                         | Duration |
+--------------------------------+----------+
| starting                       | 0.000083 |
| Executing hook on transaction  | 0.000004 |
| starting                       | 0.000009 |
| checking permissions           | 0.000006 |
| Opening tables                 | 0.000044 |
| init                           | 0.000004 |
| System lock                    | 0.000008 |
| optimizing                     | 0.000008 |
| statistics                     | 0.000019 |
| preparing                      | 0.000018 |
| executing                      | 1.202507 |
| end                            | 0.000024 |
| query end                      | 0.000005 |
| waiting for handler commit     | 0.000010 |
| closing tables                 | 0.000012 |
| freeing items                  | 0.000023 |
| cleaning up                    | 0.000013 |
+--------------------------------+----------+
17 rows in set, 1 warning (0.00 sec)
*/

我们也可以查看指定的Query lD的开销,比如show profile for query 2查询结果是一样的。在SHOWPROFILE中我们可以查看不同部分的开销,比如cpu、block.io等:

mysql> show profile cpu, block io for query 2;
+--------------------------------+----------+----------+------------+--------------+---------------+
| Status                         | Duration | CPU_user | CPU_system | Block_ops_in | Block_ops_out |
+--------------------------------+----------+----------+------------+--------------+---------------+
| starting                       | 0.000111 | 0.000066 |   0.000039 |            0 |             0 |
| Executing hook on transaction  | 0.000006 | 0.000002 |   0.000001 |            0 |             0 |
| starting                       | 0.000009 | 0.000005 |   0.000003 |            0 |             0 |
| checking permissions           | 0.000006 | 0.000004 |   0.000003 |            0 |             0 |
| Opening tables                 | 0.000044 | 0.000028 |   0.000016 |            0 |             0 |
| init                           | 0.000004 | 0.000002 |   0.000002 |            0 |             0 |
| System lock                    | 0.000008 | 0.000005 |   0.000002 |            0 |             0 |
| optimizing                     | 0.000009 | 0.000006 |   0.000004 |            0 |             0 |
| statistics                     | 0.000057 | 0.000036 |   0.000022 |            0 |             0 |
| preparing                      | 0.000023 | 0.000013 |   0.000008 |            0 |             0 |
| executing                      | 1.526632 | 1.208456 |   0.519889 |       361248 |             0 |
| end                            | 0.000021 | 0.000008 |   0.000005 |            0 |             0 |
| query end                      | 0.000005 | 0.000003 |   0.000001 |            0 |             0 |
| waiting for handler commit     | 0.000012 | 0.000008 |   0.000005 |            0 |             0 |
| closing tables                 | 0.000013 | 0.000008 |   0.000004 |            0 |             0 |
| freeing items                  | 0.000037 | 0.000024 |   0.000014 |            0 |             0 |
| cleaning up                    | 0.000016 | 0.000009 |   0.000006 |            0 |             0 |
+--------------------------------+----------+----------+------------+--------------+---------------+
17 rows in set, 1 warning (0.00 sec)

show profile的常用查询参数:

  1. ALL:显示所有的开销信息。
  2. BLOCK IO:显示块IO开销。
  3. CONTEXT SWITCHES:上下文切换开销。
  4. CPU:显示CPU开销信息。
  5. IPC:显示发送和接收开销信息
  6. MEMORY:显示内存开销信息。
  7. PAGE FAULTS:显示页面错误开销信息。
  8. SOURCE:显示和Source_function,Source_file,Source_line相关的开销信息。
  9. SWAPS:显示交换次数开销信息。

日常开发需注意的结论:

  1. converting HEAP to MyISAM:查询结果太大,内存不够,数据往磁盘上搬了。
  2. Creating tmp.table:创建临时表。先拷贝数据到临时表,用完后再删除临时表
  3. Copying to tmp table on disk:把内存中临时表复制到磁盘上,警惕!
  4. locked 。
  5. 如果在show profile诊断结果中出现了以上4条结果中的任何一条,则sql语句需要优化。

注意:

不过 SHOW PROFILE命令将被弃用,可以从 information_schema中的profiling 数据表进行查看

6. 分析查询语句:EXPLAIN

6.1概述

定位了查询慢的SQL之后,就可以使用EXPLAIN或DESCRIBE工具做针对性的分析查询语句。DESCRIBE语句的使用方法与EXPLAIN语句是一样的,并且分析结果也是一样的。

MySQL中有专门负责优化SELECT语句的优化器模块,主要功能:通过计算分析系统中收集到的统计信息,为客户端请求的Query提供它认为最优的执行计划(他认为最优的数据检索方式,但不见得是DBA认为是最优的,这部分最耗费时间)


这个执行计划展示了接下来具体执行查询的方式,比如多表连接的顺序是什么,对于每个表采用什么访问方法来具体执行查询等等。

MySQL为我们提供了EXPLAIN语句来帮助我们查看某个查询语句的具体执行计划,大家看懂EXPLAIN语句的各个输出项,可以有针对性的提升查询语句的性能。

1.能做什么?

  • 表的读取顺序
  • 数据读取操作的操作类型。
  • 哪些索引可以使用
  • 哪些索引被实际使用
  • 表之间的引用
  • 每张表有多少行被优化器查询

2.官网介绍

https://dev.mysql.com/doc/refman/5.7/en/explain-output.html

https://dev.mysql.com/doc/refman/8.0/en/explain-output.html

3.版本情况

MySQL 5.6.3以前只能 EXPLAIN SELECT ;MYSQL 5.6.3以后就可以 EXPLAIN,SELECT,UPDATE,DELETE

在5.7以前的版本中,想要显示 partitions 需要使用 explain partitions 命令;想要显示filtered需要使用 explain extended命令。在5.7版本后,默认explain直接显示partitions和filtered中的信息。

EXPLAIN SELECT * FROM student_info;
SELECT * FROM student_info LIMIT 10;
DESCRIBE DELETE FROM student_info WHERE id=2;

6.2 基本语法

EXPLAIN 或 DESCRIBE语句的语法形式如下:

EXPLAIN SELECT select_options
#或者
DESCRIBE SELECT select_options

如果我们想看看某个查询的执行计划的话,可以在具体的查询语句前边加一个 EXPLAIN ,就像这样:

EXPLAIN SELECT 1;
/*
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+----------------+
| 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 | No tables used |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+----------------+
*/

输出的上述信息就是所谓的执行计划。在这个执行计划的辅助下,我们需要知道应该怎样改进自己的查询语句以使查询执行起来更高效。其实除了以SELECT开头的查询语句,其余的DELETE、INSERT、REPLACE以及UPDATE语句等都可以加上EXPLAIN,用来查看这些语句的执行计划,只是平时我们对SELECT语句更感兴趣


注意: 执行EXPLAIN时并没有真正的执行该后面的语句,因此可以安全的查看执行计划。


EXPLAIN语句输出的各个列的作用如下:

列名 描述
id 在一个大的查询语句中每个SELECT关键字都对应一个 唯一的id
select_type SELECT关键字对应的那个查询的类型
table 表名
partitions 匹配的分区信息
type 针对单表的访问方法
possible_keys 可能用到的索引
key 实际上使用的索引
key_len 实际使用到的索引长度(单位:字节)
ref 当使用索引列等值查询时,与索引列进行等值匹配的对象信息
rows 预估的需要读取的记录条数
filtered 某个表经过搜索条件过滤后剩余记录条数的百分比
Extra 一些额外的信息

在这里把它们都列出来只是为了描述—个轮廓,让大家有一个大致的印象。

6.3 数据准备

.1. 建表

#表一
CREATE TABLE s1 (
  id INT AUTO_INCREMENT,
  key1 VARCHAR(100),
  key2 INT,
  key3 VARCHAR(100),
  key_part1 VARCHAR(100),
  key_part2 VARCHAR(100),
  key_part3 VARCHAR(100),
  common_field VARCHAR(100),
  PRIMARY KEY (id),
  INDEX idx_key1 (key1),
  UNIQUE INDEX idx_key2 (key2),
  INDEX idx_key3 (key3),
  INDEX idx_key_part(key_part1, key_part2, key_part3)
) ENGINE=INNODB CHARSET=utf8;
#表二
CREATE TABLE s2 (
  id INT AUTO_INCREMENT,
  key1 VARCHAR(100),
  key2 INT,
  key3 VARCHAR(100),
  key_part1 VARCHAR(100),
  key_part2 VARCHAR(100),
  key_part3 VARCHAR(100),
  common_field VARCHAR(100),
  PRIMARY KEY (id),
  INDEX idx_key1 (key1),
  UNIQUE INDEX idx_key2 (key2),
  INDEX idx_key3 (key3),
  INDEX idx_key_part(key_part1, key_part2, key_part3)
) ENGINE=INNODB CHARSET=utf8;
相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
相关文章
|
3月前
|
存储 SQL 关系型数据库
mysql底层原理:索引、慢查询、 sql优化、事务、隔离级别、MVCC、redolog、undolog(图解+秒懂+史上最全)
mysql底层原理:索引、慢查询、 sql优化、事务、隔离级别、MVCC、redolog、undolog(图解+秒懂+史上最全)
mysql底层原理:索引、慢查询、 sql优化、事务、隔离级别、MVCC、redolog、undolog(图解+秒懂+史上最全)
|
3月前
|
存储 关系型数据库 MySQL
MySQL数据库索引的数据结构?
MySQL中默认使用B+tree索引,它是一种多路平衡搜索树,具有树高较低、检索速度快的特点。所有数据存储在叶子节点,非叶子节点仅作索引,且叶子节点形成双向链表,便于区间查询。
100 4
|
3月前
|
存储 SQL 关系型数据库
MySQL 核心知识与索引优化全解析
本文系统梳理了 MySQL 的核心知识与索引优化策略。在基础概念部分,阐述了 char 与 varchar 在存储方式和性能上的差异,以及事务的 ACID 特性、并发事务问题及对应的隔离级别(MySQL 默认 REPEATABLE READ)。 索引基础部分,详解了 InnoDB 默认的 B+tree 索引结构(多路平衡树、叶子节点存数据、双向链表支持区间查询),区分了聚簇索引(数据与索引共存,唯一)和二级索引(数据与索引分离,多个),解释了回表查询的概念及优化方法,并分析了 B+tree 作为索引结构的优势(树高低、效率稳、支持区间查询)。 索引优化部分,列出了索引创建的六大原则
|
4月前
|
存储 关系型数据库 MySQL
MySQL覆盖索引解释
总之,覆盖索引就像是图书馆中那些使得搜索变得极为迅速和简单的工具,一旦正确使用,就会让你的数据库查询飞快而轻便。让数据检索就像是读者在图书目录中以最快速度找到所需信息一样简便。这样的效率和速度,让覆盖索引成为数据库优化师傅们手中的尚方宝剑,既能够提升性能,又能够保持系统的整洁高效。
124 9
|
5月前
|
机器学习/深度学习 关系型数据库 MySQL
对比MySQL全文索引与常规索引的互异性
现在,你或许明白了这两种索引的差异,但任何技术决策都不应仅仅基于理论之上。你可以创建你的数据库实验环境,尝试不同类型的索引,看看它们如何影响性能,感受它们真实的力量。只有这样,你才能熟悉它们,掌握什么时候使用全文索引,什么时候使用常规索引,以适应复杂多变的业务需求。
110 12
|
监控 Java 开发者
Java一分钟之-Java性能分析与调优:JProfiler, VisualVM等工具
【5月更文挑战第21天】本文介绍了Java性能优化的两个利器——JProfiler和VisualVM。JProfiler通过CPU Profiler、内存分析器和线程视图帮助解决过度CPU使用、内存泄漏和线程阻塞问题;VisualVM则聚焦于GC行为调整和类加载优化,以减少内存压力和提高应用性能。使用这些工具进行定期性能检查,是提升Java应用效率的关键。
400 0
|
11月前
|
缓存 监控 Linux
Linux性能分析利器:全面掌握perf工具
【10月更文挑战第18天】 在Linux系统中,性能分析是确保软件运行效率的关键步骤。`perf`工具,作为Linux内核自带的性能分析工具,为开发者提供了强大的性能监控和分析能力。本文将全面介绍`perf`工具的使用,帮助你成为性能优化的高手。
596 1
|
11月前
|
缓存 监控 Linux
掌握Linux性能分析:深入探索perf工具
【10月更文挑战第26天】
496 1
|
SQL 缓存 关系型数据库
MySQL高级篇——性能分析工具
MySQL的慢查询日志,用来记录在MySQL中响应时间超过阀值的语句,具体指运行时间超过long-query_time值的SQL,则会被记录到慢查询日志中。long_query_time的默认值为 10,意思是运行10秒以上(不含10秒)的语句,认为是超出了我们的最大忍耐时间值。它的主要作用是,帮助我们发现那些执行时间特别长的 SOL 查询,并且有针对性地进行优化,从而提高系统的整体效率。当我们的数据库服务器发生阻塞、运行变慢的时候,检查一下慢查询日志,找到那些慢查询,对解决问题很有帮助。
MySQL高级篇——性能分析工具
|
12月前
|
Web App开发 监控 JavaScript
一些常用的 Vue 性能分析工具
【10月更文挑战第2天】
675 1

推荐镜像

更多