数据库基础

一、 锁

  • 根据加锁的范围,MySQL里面的锁大致可以分成全局锁、表级锁和行锁三类

1. 行锁

1. InnoDB的锁

  • 在InnoDB事务中,行锁是在需要的时候才加上的,但并不是不需要了就立刻释放,而是要等到事务结束时才释放。这个就是两阶段锁协议。

    • 如果你的事务中需要锁多个行,要把最可能造成锁冲突、最可能影响并发度的锁尽量往后放。
  • 行级锁(InnoDB存储引擎实现了两种标准的)

    • 共享锁 允许事务读一行数据
    • 排他锁 允许事务删除或更新一行数据
  • 意向锁(表锁)

    • 意向共享锁(IS Lock),事务想要获得一张表中某几行的共享锁
    • 意向排他锁(IX Lock),事务想要获得一张表中某几行的排他锁

2 锁的类型

  • 一致性非锁定读

    • 是指InnoDB存储引擎通过行多版本控制(multi versioning)的方式来读取当前执行时间数据库中行的数据
    • 如果读取的行正在执行DELETE或UPDATE操作,这时读取操作不会因此去等待行上锁的释放,MVCC 实现。
  • 一致性锁定读

    • 事务的隔离级别为REPEATABLE READ模式下,InnoDB存储引擎的SELECT操作使用一致性非锁定读。但是在某些情况下,用户需要显式地对数据库读取操作进行加锁以保证数据逻辑的一致性
    • 两种一致性的锁定读操作
      • SELECT…FOR UPDATE
        • 加一个X锁,其他事务不能对已锁定的行加上任何锁
      • SELECT…LOCK IN SHARE MODE
        • 对读取的行记录加一个S锁,其他事务可以向被锁定的行加S锁,但是如果加X锁,则会被阻塞
      • 必须在一个事务中,务必加上BEGIN,START TRANSACTION或者SET AUTOCOMMIT=0
  • 自增长与锁

    • 每个含有自增长值的表都有一个自增长计数器
    • 当对含有自增长的计数器的表进行插入操作时,这个计数器会被初始化,执行如下的语句来得到计数器的值:
      • SELECT MAX(auto_inc_col)FROM t FOR UPDATE;
  • 外键和锁

    • 对于一个外键列,如果没有显式地对这个列加索引,InnoDB存储引擎自动对其加一个索引,因为这样可以避免表锁

3 锁的算法

  • Record Lock:单个行记录上的锁

  • Gap Lock:间隙锁,锁定一个范围,但不包含记录本身

  • Next-Key Lock∶Gap Lock+Record Lock,锁定一个范围,并且锁定记录本身

    • (]
  • rr 隔离级别

    • select * where id = xx for update
      • id 不存在,行锁 + 间隙锁
      • id 存在 行锁
      • 范围查询, 间隙锁

3.1 包含了两个“原则”、两个“优化”和一个“bug”。(mysql实战45讲)

  • 原则
    1. 加锁的基本单位是next-key lock。next-key lock是前开后闭区间。
    2. 查找过程中访问到的对象才会加锁。
      • 访问到的对象都要加锁。
  • 优化
    1. 索引上的等值查询,给唯一索引加锁的时候,next-key lock退化为行锁。
    2. 索引上的等值查询,向右遍历时且最后一个值不满足等值条件的时候,next-key lock退化为间隙锁。
  • bug
    • 唯一索引上的范围查询会访问到不满足条件的第一个值为止。

3.2 案例

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

insert into t values(0,0,0),(5,5,5),
(10,10,10),(15,15,15),(20,20,20),(25,25,25);

1.等值查询间隙锁

sessionA sessionB sessionC
BEGIN; update t SET d=d+1 WHERE id = 7;
. INSERT INTO t VALUES (8,8,8); (bocked)
. . update t SET d=d+1 WHERE id = 10;(Query OK)
  • 表中没有 id=7 的记录
    • 加锁的基本单位是next-key lock。next-key lock是前开后闭区间。
      • seesionA 加锁 (5,10]
    • 索引上的等值查询,向右遍历时且最后一个值不满足等值条件的时候,next-key lock退化为间隙锁。
      • id=10 不满足查询条件,锁的范围优化成(5,10)
  • sessionB 记录会被锁主, SeesionC 正常

2.非唯一索引等值锁

sessionA sessionB sessionC
BEGIN; SELECT id FROM t WHERE c=5 LOCK IN SHARE MODE ;
. UPDATE t set d=d+1 WHERE id=5; (Query OK)
. . INSERT INTO t VALUES (7,7,7); (bocked)
  • 加锁的基本单位是next-key lock。然后非唯一索引要到不满足的条件,并且 扫描到的数据被锁住。
    • sessionA (0,10)
  • 只有访问到的对象才会加锁,这个查询使用覆盖索引,并不需要访问主键索引,所以主键索引上没有加任何锁
    • sessionB 能正常执行。

** 3. 主键索引范围锁**

2 全局锁

1. 加全局锁的方法

Flush tables with read lock (FTWRL)
  • 当你需要让整个库处于只读状态的时候,可以使用这个命令,之后其他线程的以下语句会被阻塞:
    • 数据更新语句(数据的增删改)、
    • 数据定义语句(包括建表、修改表结构等)
    • 更新类事务的提交语句。

2. 使用场景

  1. 全库逻辑备份
    • 通过FTWRL 来对整个库做备份是危险的
      • 如果在主库备份,备份期间,不能执行更新,业务基本停摆。
      • 如果在从库备份,备份从库不能执行主库同步过来的binlog,会导致主从延迟。
    • 一致性视图方法。
      • 在可重复读隔离级别下开启一个事务。
        • 官方自带的逻辑备份工具是mysqldump
        • 当mysqldump使用参数–single-transaction的时候,导数据之前就会启动一个事务,来确保拿到一致性视图。
        • 而由于MVCC的支持,这个过程中数据是可以正常更新的。
      • 一致性读是好,但前提是引擎要支持这个隔离级别
        • MyISAM这种不支持事务的引擎,如果备份过程中有更新,总是只能取到最新的数据,那么就破坏了备份的一致性。
      • single-transaction方法只适用于所有的表使用事务引擎的库
    • 既然要全库只读,为什么不使用set global readonly=true的方式
      • 一是,在有些系统中,readonly的值会被用来做其他逻辑,比如用来判断一个库是主库还是备库。因此,修改global变量的方式影响面更大,我不建议你使用。
      • 二是,在异常处理机制上有差异。如果执行FTWRL命令之后由于客户端发生异常断开,那么MySQL会自动释放这个全局锁,整个库回到可以正常更新的状态。而将整个库设置为readonly之后,如果客户端发生异常,则数据库就会一直保持readonly状态,这样会导致整个库长时间处于不可写状态,风险较高。

3. 表级锁

  • MySQL里面表级别的锁有两种:一种是表锁,一种是元数据锁(meta data lock,MDL)。

1. 表锁

  1. 语法
    • lock tables语法 除了会限制别的线程的读写外,也限定了本线程接下来的操作对象。
# 加锁
lock tables … read/write

# 释放锁 ,也可以在客户端断开的时候自动释放
unlock tables
  1. 例子
# A 线程执行, 线程A在执行unlock tables之前,也只能执行读t1、读写t2的操作。
lock tables t1 read, t2 write; 

2. 元数据锁

  • MDL不需要显式使用,在访问一个表的时候会被自动加上。
    • MDL的作用是,保证读写的正确性。
      • 你可以想象一下,如果一个查询正在遍历一个表中的数据,而执行期间另一个线程对这个表结构做变更,删了一列,那么查询线程拿到的结果跟表结构对不上,肯定是不行的。
    • 在MySQL 5.5版本中引入了MDL
  1. 功能
  • 当对一个表做增删改查操作的时候,加MDL读锁;当要对表做结构变更操作的时候,加MDL写锁。

    • 读锁之间不互斥,因此你可以有多个线程同时对一张表增删改查。
    • 读写锁之间、写锁之间是互斥的,用来保证变更表结构操作的安全性。
      • 如果有两个线程要同时给一个表加字段,其中一个要等另一个执行完才能开始执行。
  • 虽然MDL锁是系统默认会加的,但却是你不能忽略的一个机制。

    • 我经常看到有人掉到这个坑里:给一个小表加个字段,导致整个库挂了。
      • 事务中的MDL锁,在语句执行开始时申请,但是语句结束后并不会马上释放,而会等到整个事务提交后再释放。

3. 使用

  1. 如何安全地给小表加字段?
    • 解决:
      • 首先我们要解决长事务,事务不提交,就会一直占着MDL锁。
      • 在MySQL的information_schema 库的 innodb_trx 表中,你可以查到当前执行中的事务。
      • 如果你要做DDL变更的表刚好有长事务在执行,要考虑先暂停DDL,或者kill掉这个长事务。
    • 如果你要变更的表是一个热点表,虽然数据量不大,但是上面的请求很频繁,而你不得不加个字段,你该怎么做呢?
      • 这时候kill可能未必管用,因为新的请求马上就来了。
      • 比较理想的机制是,在alter table语句里面设定等待时间,如果在这个指定的等待时间里面能够拿到MDL写锁最好,拿不到也不要阻塞后面的业务语句,先放弃。之后开发人员或者DBA再通过重试命令重复这个过程。
ALTER TABLE tbl_name NOWAIT add column ...
ALTER TABLE tbl_name WAIT N add column ... 

二、 基础概念

1. 理论基础

1. 范式

  • 第一范式 属性不可再分
  • 第二范式 满足第一范式,非主属性不存在对主属性的部分依赖(如联合主键,某个属性只依赖其中一部分)
  • 第三范式 满足第二范式,属性不存在对非主属性的传递依赖。

1. binglog

1. 作用

  • MySQL上下分为 Server 层和引擎层,不同存储引擎中的日志格式是不同的,由于要对多引擎支持,必须在 Server 层设计逻辑日志以透明化不同存储引擎,而这个逻辑日志就是Binlog(归档日志)。
    • 当有数据修改请求时,primary会产生包含该修改操作的Binlog,并发送给replica,replica通过回放该Binlog以执行和primary同样的修改。
    • 还可用于备份点还原

2. 与redo log 对比

区别\日志 binglog redo log
层次 是MySQL的Server层实现的,所有引擎都可以使用。 redo log是InnoDB引擎特有的
存储 binlog是逻辑日志,记录的是这个语句的原始逻辑,比如“给ID=2这一行的c字段加1 ”。 redo log是物理日志,记录的是“在某个数据页上做了什么修改”
实现细节 redo 追加写”是指binlog文件写到一定大小后会切换到下一个,并不会覆盖以前的日志。 redo log是循环写的,空间固定会用完;binlog是可以追加写入的

3. 两阶段提交保证 binglog, redo log一致性

  • 对某个id + c列1 操作


    image.png

4. binlog的日志格式

[mysqld]    
binlog-format=ROW #选择row模式  

# 假如
mysql> CREATE TABLE `t` (
  `id` int(11) NOT NULL,
  `a` int(11) DEFAULT NULL,
  `t_modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  KEY `a` (`a`),
  KEY `t_modified`(`t_modified`)
) ENGINE=InnoDB;

insert into t values(1,1,'2018-11-13');
insert into t values(2,2,'2018-11-12');
insert into t values(3,3,'2018-11-11');
insert into t values(4,4,'2018-11-10');
insert into t values(5,5,'2018-11-09');


# 执行这条语句
delete from t /*comment*/  where a>=4 and t_modified<='2018-11-10' limit 1;
binglog格式 内容 优点 缺点 上面sql binlog图片
Statement 记录每一条修改的sql语句 数据量相对 row少 在主库与从库的不同上下文下,修改的sql语句结果可能不一样,例如命中的索引之类的。
image.png
Row 记录每一条修改sql语句,影响的 每一行 数据的修改 主从库同步不会有歧义 数据量相对Statement 大很多 2
image.png
借助 mysqlbinlog解析和查看binlog中的内容。(mysqlbinlog -vv data/master.000001 --start-position=8900;)
image.png
(@1=4、 @2=4) 只记录id==4 的这条记录
Mixed MySQL自己会判断这条SQL语句是否可能引起主备不一致,如果有可能,就用row格式,否则就用statement格式

三、 事务的实现

  • 原子性、一致性、持久性通过数据库的redo log和undo log来完成
  • redo log称为重做日志,用来保证事务的原子性和持久性
    • redo通常是物理日志,记录的是页的物理修改操作
  • undo log用来保证事务的一致性
    • undo是逻辑日志,根据每行记录进行记录。

1 redo

  • InnoDB引擎 特有的,引擎层的日志

1. 持久化

  • 当事务提交(COMMIT)时,必须先将该事务的所有日志写入到重做日志文件进行持久化,待事务的COMMIT操作完成才算完成

2. 组成

  • 重做日志来实现事务的持久性,两部分组成。
    • 重做日志缓冲(redo log buffer)
    • 重做日志文件(redo log file)

3. 持久化到磁盘机制

  • innodb_flush_log_at_trx_commit 控制重做日志刷新到磁盘的策略 默认值为1
    • 0 事务提交时不进行写入重做日志操作,这个操作仅在master thread中完成,而在master thread中每1秒会进行一次重做日志文件的fsync操作
    • 1 默认值 事务提交时必须调用一次fsync操作
    • 2 事务提交时将重做日志写入重做日志文件,但仅写入文件系统的缓存中,不进行fsync操作
      • mysql 宕机,操作系统不宕机,不会事务丢失
      • 操作系统宕机,事务会丢失。

2 undo

  • 作用 回滚操作与mvcc

  • undo log 格式

    • insert undo log
      • 记录 insert 操作时产生的undo log
        • 因为insert 操作的记录只对当前事务可见,该undo log 在事务提交后可以直接删除,不需要进行purge操作。
      • 11 TRX_UNDO_INSERT_REC
    • update undo log
      • 记录 delete 和 update操作产生的undo log
        • 需要提供MVCC机制,事务提交不能进行删除,提交放入到undo log链表,等待purge线程进行最后的删除。
      • 分类
        • 12 TRX_UNDO_UPD_EXIST_REC 更新non-delete-mark的记录 更新非主键属性
        • 13 TRX_UNDO_UPD_DEL_REC 将delete的记录标记为not delete
        • 当插入一条 与标记为删除记录相同的主键时。
        • 14 TRX_UNDO_DEL_MARK_REC 将记录标记为delete 更新主键/非主键属性

3 mvcc

  • 一篇还行的介绍文章

    image.png

  • 表的隐藏列

    • TRX_ID 记录操作该数据 事务的是事务id
    • roll_point 指向上一个版本数据在undo log 位置指针
    • DB_ROW_ID 行标识 ,如果表没有主键,InnoDB 会自动生成一个隐藏主键。
    • 每条记录头信息(record header)有一个专门的bit(deleted_flag) 表示当前记录是否已经删除。
  • insert delete update

    • insert 产生一条新纪录。
      • trx_id 是当前插入记录的事务id。
    • delete
      • 标记删除
      • trx_id 是当前删除记录的事务id。
    • update
      • update 主键
        • 添加一条新纪录
        • 新纪录 roll_point 指向 旧纪录
          • 旧纪录 roll_point,TRX_ID不动

1 ReadView

  • 每一个sql语句执行前都会得到一个 readView。

  • 关键属性

    • trx_ids 当前系统活跃(未提交)事务版本号集合
    • low_limit_id 创建当前read view 时 当前系统最大事务版本号+1
    • up_limit_id 创建当前read view 时 系统正处于活跃事务最小版本号
    • creator_trx_id 创建当前read view的事务版本号
  • 匹配条件

    • 数据事务ID < ReadView.up_limit_id
      • 显示 开启事务之前存在的数据
    • 数据事务ID >= ReadView.low_limit_id
      • 不显示 开启事务之后新加的数据
    • up_limit_id <= 数据事务ID < low_limit_id 则与活跃事务集合trx_ids里匹配(数据可能是 当前事务开始的时候还没有提交的)
      • 数据事务ID不存在于trx_ids 集合
        • 显示 ReadView 产生的时候已经commit
      • 数据事务ID存在于trx_ids 集合
        • 数据的事务ID等于creator_trx_id
            • 显示 当前事务自己生成的
            • 不显示 ReadView产生的数据还没提交,又不是自己的。
    • 当前数据事务ID 不满足 ReadView条件,从undo log 获取历史版本。
      • 历史版本再来和 ReadView条件匹配,直到找到一条满足条件的历史数据,或者找不到返回空。
  • 不同隔离级别 对Read View 的不同

    • 读已提交的
      • 一个事务中每一次 SELECT 查询都会获取一次Read View
    • 重复读
      • 一个事务只在第一次SELECT的时候,会获取一次Read View,后面SELECT 都会复用这个Read View.

2. 当前读和快照读

  • InnoDB 默认可重复读 ,通过 "行排他锁+MVCC" 一起实现的。
2.1 当前读
  • select ... lock in share mode
  • select ... for update
  • insert
  • update
  • delete
2.2 快照读
  • 简单的select操作(当然不包括 select ... lock in share mode, select ... for update)

3 purge

  • 用于最终完成delete和update操作。因为要支持MVcc,若该行记录已不被任何其他事务引用,那么就可以进行真正的delete操作。

四、 慢查询

  • 如何定位到这些糟糕的查询语句呢

1. 基础配置

1. 配置

# 查看是否开启慢查询以及路径
show variables like '%slow_query_log%';


# 开启慢查询 ,MySQL重启失效 配置长期有效,请在my.cnf中进行配置
set global slow_query_log = 1;

# 慢查询的阈值时间单位s
set global long_query_time = 10;

# 查看慢查询的阈值时间 默认大于10记录
show variables like 'long_query_time';

# 查看慢查询阈值 临时设置的
show global variables like 'long_query_time';

# 查询慢查询文件目录
show variables like 'slow_query%';
# 输出
+-------------------+------------------------------------+
|Variable_name      |Value                               |
+-------------------+------------------------------------+
|slow_query_log     |ON                                  |
|slow_query_log_file|/var/lib/mysql/2757e9798d42-slow.log|
+-------------------+------------------------------------+

# 查看慢查询日志
SELECT  sleep(11);
root@2757e9798d42:/# more /var/lib/mysql/2757e9798d42-slow.log

mysqld, Version: 5.7.35 (MySQL Community Server (GPL)). started with:
Tcp port: 3306  Unix socket: /var/lib/mysql/mysql.sock
Time                 Id Command    Argument
# Time: 2023-02-01T07:31:29.686596Z
# User@Host: root[root] @  [172.17.0.1]  Id:    10
# Query_time: 11.007296  Lock_time: 0.000000 Rows_sent: 1  Rows_examined: 0
use performance_schema;
SET timestamp=1675236689;
/* ApplicationName=DataGrip 2020.1.5 */ SELECT  sleep(11);

2. 工具分析

1. mysqldumpslow

  • 语法
# 一部分参数
-s, 是表示按照何种方式排序,
    c: 访问计数
    l: 锁定时间
    r: 返回记录
    t: 查询时间
    al:平均锁定时间
    ar:平均返回记录数
    at:平均查询时间
-t, 是top n的意思,即为返回前面多少条的数据;
-g, 后边可以写一个正则匹配模式,大小写不敏感的;
  • 案例
#得到返回记录集最多的10个SQL。
mysqldumpslow -s r -t 10 /database/mysql/mysql06_slow.log
# 输出
mysqldumpslow -s r -t 10  /var/lib/mysql/2757e9798d42-slow.log

Reading mysql slow query log from /var/lib/mysql/2757e9798d42-slow.log
Count: 1  Time=11.00s (11s)  Lock=0.00s (0s)  Rows=1.0 (1), root[root]@[172.17.0.1]
  /* ApplicationName=DataGrip N.N.N */ SELECT now(),  sleep(N)

Count: 1  Time=0.00s (0s)  Lock=0.00s (0s)  Rows=0.0 (0), 0users@0hosts
  mysqld, Version: N.N.N (MySQL Community Server (GPL)). started with:
  # Time: N-N-01T07:N:N.686596Z
  # User@Host: root[root] @  [N.N.N.N]  Id:    N
  # Query_time: N.N  Lock_time: N.N Rows_sent: N  Rows_examined: N
  use performance_schema;
  SET timestamp=N;
  /* ApplicationName=DataGrip N.N.N */ SELECT  sleep(N)

Died at /usr/bin/mysqldumpslow line 167, <> chunk 2.

#得到访问次数最多的10个SQL
mysqldumpslow -s c -t 10 /database/mysql/mysql06_slow.log

#得到按照时间排序的前10条里面含有左连接的查询语句。
mysqldumpslow -s t -t 10 -g “left join” /database/mysql/mysql06_slow.log

#另外建议在使用这些命令时结合 | 和more 使用 ,否则有可能出现刷屏的情况。
mysqldumpslow -s r -t 20 /mysqldata/mysql/mysql06-slow.log | more




五,慢sql 优化

1 查询优化

1 explain

  • 参考
  • link
  • explain
    • image.png
      • id 查询中select 子句或者操作表顺序,数字越大越先被执行,相同则按先后顺序
      • slect_type 查询类型
        • SIMPLE(普通查询,即没有联合查询、子查询)、
        • PRIMARY(主查询)、
        • UNION(UNION 中后面的查询)、
        • SUBQUERY(子查询)等。
      • table 当前执行计划查询的表,如果给表起别名了,则显示别名信息
      • partitions 匹配的分区
      • type 数据访问的类型
        • system/const 表中只有一行数据匹配,此时根据索引查询一次就能找到对应的数据。
        • eq_ref 唯一性索引扫描 对于每个索引键,表中只有一条记录与之匹配,常见于主键或唯一索引扫描
        • ref 非唯一性索引扫描,还可见于唯一索引最左原则匹配扫描。返回匹配某个单独值的所有行
          • 本质上也是一种索引访问,返回所有匹配某个单独值的行 然而可能会找到多个符合条件的行,应该属于查找和扫描的混合体
        • range 索引范围扫描,比如,<,>,between 等操作。
          • 使用一个索引来选择行,key列显示使用了哪个索引 一般就是在你的where语句中出现between、<>、in等的查询
        • index 全索引扫描
        • all 遍历全表以找到匹配行
          • index all 区别 ndex只遍历索引树,通常比All快 因为索引文件通常比数据文件小,也就是虽然all和index都是读全表,但index是从索引中读取的,而all是从硬盘读的
      • possible_keys 可能用到的索引,不一定用到
      • key 实际用到的索引
      • key_len 索引使用的字节数
      • ref 显示联合索引的哪一列被使用了
      • rows 大致估算查询记录,需要读取的行数
        • 估算 SQL 要查找到结果集需要扫描读取的数据行数.
      • filtered 查询 占这表数据的百分比
      • extra 额外信息
        • using filesort(额外的外部排序)
        • using temporary (构建了临时表,比如排序的时候,子查询)
        • using where (对索引扫描的数据再次根据where 过滤出了结果)
        • Using index(用了索引)
        • Using index condition(条件过滤索引,再回表)

2. 性能分析 Optimizer trace

  1. 信息

    • Optimizer trace并不是自动就会默认开启的
    • 可以看到expain 没有的信息
  2. 例子

-- 开启trace
set optimizer_trace="enabled=on";
-- 执行查询sql
EXPLAIN  SELECT * from user_success_medal WHERE   medal_id >= 5266971053548122239 and user_id = 5236743288469330988    ;
-- 查询trace字段
select TRACE from INFORMATION_SCHEMA.OPTIMIZER_TRACE;
-- 关闭trace工具
set session optimizer_trace="enabled=off";

3. Profiles

  • SQL性能统计
  1. 语法

SHOW PROFILE [type [, type] ... ]
[FOR QUERY n]
[LIMIT row_count [OFFSET offset]]

type参数:
| ALL:显示所有开销信息
| BLOCK IO:阻塞的输入输出次数
| CONTEXT SWITCHES:上下文切换相关开销信息
| CPU:显示CPU的相关开销信息 
| IPC:接收和发送消息的相关开销信息
| MEMORY :显示内存相关的开销,目前无用
| PAGE FAULTS :显示页面错误相关开销信息
| SOURCE :列出相应操作对应的函数名及其在源码中的调用位置(行数) 
| SWAPS:显示swap交换次数的相关开销信息
  1. 注意点
  • MySQL 是在 5.0.37 版本之后才支持 Show Profile 功能的
  • 通过命令查看是否支持
select @@have_profiling;

# 输出
YES
  • Show Profiles
    • 显示最近发给服务器的 SQL 语句,默认情况下是记录最近已执行的 15 条记录,
    • 我们可以重新设置 profiling_history_size 增大该存储记录,最大值为 100
  • Show Profile for Query ID
    • 查看到对应 Query_ID 的 SQL 语句在执行过程中线程的每个状态所消耗的时间了:
# 查看 profiling 状态
show variables like "%pro%";
# 输出
+-------------------------+-----+
|Variable_name            |Value|
+-------------------------+-----+
|have_profiling           |YES  |
|profiling                |ON   |
|profiling_history_size   |15   |
|protocol_version         |10   |
|proxy_user               |     |
|slave_compressed_protocol|OFF  |
|stored_program_cache     |256  |
+-------------------------+-----+

# 关闭 profiling
set profiling=0;

  1. 例子
  • profiles 例子
SELECT * from user_member_record ;
Show Profiles;

# 输出
+--------+----------+------------------------------------------------------------------------+
|Query_ID|Duration  |Query                                                                   |
+--------+----------+------------------------------------------------------------------------+
|516     |0.00090925|SHOW WARNINGS                                                           |
|517     |0.0018765 |/* ApplicationName=DataGrip 2020.1.5 */ select database()               |
|518     |0.000656  |SHOW WARNINGS                                                           |
|519     |0.000784  |SHOW WARNINGS                                                           |
|520     |0.0011405 |/* ApplicationName=DataGrip 2020.1.5 */ SET net_write_timeout=600       |
|521     |0.001045  |/* ApplicationName=DataGrip 2020.1.5 */ SET SQL_SELECT_LIMIT=501        |
|522     |0.00368375|/* ApplicationName=DataGrip 2020.1.5 */ SELECT * from user_member_record|
+--------+----------+------------------------------------------------------------------------+


Show Profile for Query 281;

# 输出
+--------------+--------+
|Status        |Duration|
+--------------+--------+
|starting      |0.000142|
|Opening tables|0.000497|
|query end     |0.000112|
|closing tables|0.000099|
|freeing items |0.000149|
|cleaning up   |0.000286|
+--------------+--------+


4. performance_schema的digest统计

USE performance_schema;

select 1, sleep(1);
select * from events_statements_summary_by_digest;
# 输出
+-----------+--------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------+--------------+--------------+--------------+--------------+-------------+----------+------------+-----------------+-------------+-----------------+---------------------------+----------------------+--------------------+--------------------------+----------------+----------------------+---------------+---------------------+--------------+-------------+-------------+-----------------+----------------------+-------------------+-------------------+
|SCHEMA_NAME|DIGEST                          |DIGEST_TEXT                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |COUNT_STAR|SUM_TIMER_WAIT|MIN_TIMER_WAIT|AVG_TIMER_WAIT|MAX_TIMER_WAIT|SUM_LOCK_TIME|SUM_ERRORS|SUM_WARNINGS|SUM_ROWS_AFFECTED|SUM_ROWS_SENT|SUM_ROWS_EXAMINED|SUM_CREATED_TMP_DISK_TABLES|SUM_CREATED_TMP_TABLES|SUM_SELECT_FULL_JOIN|SUM_SELECT_FULL_RANGE_JOIN|SUM_SELECT_RANGE|SUM_SELECT_RANGE_CHECK|SUM_SELECT_SCAN|SUM_SORT_MERGE_PASSES|SUM_SORT_RANGE|SUM_SORT_ROWS|SUM_SORT_SCAN|SUM_NO_INDEX_USED|SUM_NO_GOOD_INDEX_USED|FIRST_SEEN         |LAST_SEEN          |
+-----------+--------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------+--------------+--------------+--------------+--------------+-------------+----------+------------+-----------------+-------------+-----------------+---------------------------+----------------------+--------------------+--------------------------+----------------+----------------------+---------------+---------------------+--------------+-------------+-------------+-----------------+----------------------+-------------------+-------------------+
|NULL       |1fa9e9651540b0e65d6c065f4bdfb036|SELECT @@SESSION . `auto_increment_increment` AS `auto_increment_increment` , @@`character_set_client` AS `character_set_client` , @@`character_set_connection` AS `character_set_connection` , @@`character_set_results` AS `character_set_results` , @@`character_set_server` AS `character_set_server` , @@`collation_server` AS `collation_server` , @@`collation_connection` AS `collation_connection` , @@`init_connect` AS `init_connect` , @@`interactive_timeout` AS `interactive_timeout` , @@`license` AS `license` , @@`lower_case_table_names` AS `lower_case_table_names` , @@`max_allowed_packet` AS `max_allowed_packet` , @@`net_write_timeout` AS `net_write_timeout` , @@`performance_schema` AS `performance_schema` , @@`query_cache_size` AS `query_cache_size` , @@`query_cache_type` AS `query_cache_type` , @@`sql_mode` AS `sql_mode` , @@`system_time_zone` AS `system_time_zone` , @@`time_zone` AS `time_zone` , @@`transaction_isolation` AS `transaction_isolation` , @@|9         |20344100000   |204800000     |2260455000    |15897000000   |0            |0         |18          |0                |9            |0                |0                          |0                     |0                   |0                         |0               |0                     |0              |0                    |0             |0            |0            |0                |0                     |2023-02-01 11:51:00|2023-02-01 14:44:40|
|NULL       |feaff321c54a9c8e1e9508628f7a5a05|SHOW WARNINGS                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |202       |23143500000   |60400000      |114571000     |600400000     |0            |0         |0           |0                |0            |0                |0                          |0                     |0                   |0                         |0               |0                     |0              |0                    |0             |0            |0            |0                |0                     |2023-02-01 11:51:00|2023-02-01 14:44:40|
+-----------+--------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------+--------------+--------------+--------------+--------------+-------------+----------+------------+-----------------+-------------+-----------------+---------------------------+----------------------+--------------------+--------------------------+----------------+----------------------+---------------+---------------------+--------------+-------------+-------------+-----------------+----------------------+-------------------+-------------------+

你可能感兴趣的:(数据库基础)