MySQL 的执行原理(三)

5.4. InnoDB 中的统计数据

我们前边唠叨查询成本的时候经常用到一些统计数据,比如通过 SHOW
TABLE STATUS 可以看到关于表的统计数据,通过 SHOW INDEX 可以看到关于索引
的统计数据,那么这些统计数据是怎么来的呢?它们是以什么方式收集的呢?

5.4.1. 统计数据存储方式

InnoDB 提供了两种存储统计数据的方式:
永久性的统计数据,这种统计数据存储在磁盘上,也就是服务器重启之后这些统计数据还在。
非永久性的统计数据,这种统计数据存储在内存中,当服务器关闭时这些这些统计数据就都被清除掉了,等到服务器重启之后,在某些适当的场景下才会重新收集这些统计数据。
MySQL 给我们提供了系统变量 innodb_stats_persistent 来控制到底采用哪种方式去存储统计数据。在 MySQL 5.6.6 之前,innodb_stats_persistent 的值默认是OFF,也就是说 InnoDB 的统计数据默认是存储到内存的,之后的版本中 innodb_stats_persistent 的值默认是 ON,也就是统计数据默认被存储到磁盘中。

SHOW VARIABLES LIKE 'innodb_stats_persistent';

在这里插入图片描述
不过最近的 MySQL 版本都基本不用基于内存的非永久性统计数据了,所以我们也就不深入研究。
不过 InnoDB 默认是以表为单位来收集和存储统计数据的,也就是说我们可以把某些表的统计数据(以及该表的索引统计数据)存储在磁盘上,把另一些表的统计数据存储在内存中。怎么做到的呢?我们可以在创建和修改表的时候通过指定 STATS_PERSISTENT 属性来指明该表的统计数据存储方式:

CREATE TABLE 表名 (...) Engine=InnoDB, STATS_PERSISTENT = (1|0);
ALTER TABLE 表名 Engine=InnoDB, STATS_PERSISTENT = (1|0);

当 STATS_PERSISTENT=1 时,表明我们想把该表的统计数据永久的存储到磁盘上,当 STATS_PERSISTENT=0 时,表明我们想把该表的统计数据临时的存储到内存中。如果我们在创建表时未指定 STATS_PERSISTENT 属性,那默认采用系统变量 innodb_stats_persistent 的值作为该属性的值。

5.4.2. 基于磁盘的永久性统计数据

当我们选择把某个表以及该表索引的统计数据存放到磁盘上时,实际上是把这些统计数据存储到了两个表里:

SHOW TABLES FROM mysql LIKE 'innodb%';

在这里插入图片描述
可以看到,这两个表都位于 mysql 系统数据库下边,其中:
innodb_table_stats 存储了关于表的统计数据,每一条记录对应着一个表的统计数据。
innodb_index_stats 存储了关于索引的统计数据,每一条记录对应着一个索引的一个统计项的统计数据。

5.4.2.1. innodb_table_stats

直接看一下这个 innodb_table_stats 表中的各个列都是干嘛的:
在这里插入图片描述
database_name 数据库名
table_name表名
last_update 本条记录最后更新时间
n_rows 表中记录的条数
clustered_index_size 表的聚簇索引占用的页面数量
sum_of_other_index_sizes 表的其他索引占用的页面数量
我们直接看一下这个表里的内容:

SELECT * FROM mysql.innodb_table_stats;

在这里插入图片描述
几个重要统计信息项的值如下:

  • n_rows 的值是 10350,表明 order_exp 表中大约有 10350 条记录,注意这个数据是估计值。
  • clustered_index_size 的值是 97,表明 order_exp 表的聚簇索引占用 97 个页面,这个值是也是一个估计值。
  • sum_of_other_index_sizes 的值是 81,表明 order_exp 表的其他索引一共占用81 个页面,这个值是也是一个估计值。
    n_rows 统计项的收集
    InnoDB 统计一个表中有多少行记录是这样的:
    按照一定算法(并不是纯粹随机的)选取几个叶子节点页面,计算每个页面中主键值记录数量,然后计算平均一个页面中主键值的记录数量乘以全部叶子节点的数量就算是该表的 n_rows 值。

可以看出来这个 n_rows 值精确与否取决于统计时采样的页面数量,MySQL用名为 innodb_stats_persistent_sample_pages 的系统变量来控制使用永久性的统计数据时,计算统计数据时采样的页面数量。该值设置的越大,统计出的 n_rows值越精确,但是统计耗时也就最久;该值设置的越小,统计出的 n_rows 值越不精确,但是统计耗时特别少。所以在实际使用是需要我们去权衡利弊,该系统变量的默认值是 20。
InnoDB 默认是以表为单位来收集和存储统计数据的,我们也可以单独设置某个表的采样页面的数量,设置方式就是在创建或修改表的时候通过指定STATS_SAMPLE_PAGES 属性来指明该表的统计数据存储方式.

CREATE TABLE 表名 (…) Engine=InnoDB, STATS_SAMPLE_PAGES = 具体的采样页面数量;
ALTER TABLE 表名 Engine=InnoDB, STATS_SAMPLE_PAGES = 具体的采样页面数量;
如果我们在创建表的语句中并没有指定 STATS_SAMPLE_PAGES 属性的话,将默认使用系统变量 innodb_stats_persistent_sample_pages 的值作为该属性的值。
clustered_index_size 和 sum_of_other_index_sizes 统计项的收集牵涉到很具体的 InnoDB 表空间的知识和存储页面数据的细节,我们就不深入讲解了。

5.4.2.2. innodb_index_stats

直接看一下这个 innodb_index_stats 表中的各个列都是干嘛的:

desc mysql.innodb_index_stats;

在这里插入图片描述
字段名 描述
database_name 数据库名
table_name表名
index_name 索引名
last_update 本条记录最后更新时间
stat_name 统计项的名称
stat_value 对应的统计项的值
sample_size为生成统计数据而采样的页面数量
stat_description对应的统计项的描述
innodb_index_stats 表的每条记录代表着一个索引的一个统计项。可能这会 大家有些懵逼这个统计项到底指什么,别着急,我们直接看一下关于 order_exp 表的索引统计数据都有些什么:

mysql> SELECT * FROM mysql.innodb_index_stats WHERE table_name =
'order_exp';

在这里插入图片描述
先查看 index_name 列,这个列说明该记录是哪个索引的统计信息,从结果中我们可以看出来,PRIMARY 索引(也就是主键)占了 3 条记录,idx_expire_time 索引占了 6 条记录。
针对 index_name 列相同的记录,stat_name 表示针对该索引的统计项名称,stat_value 展示的是该索引在该统计项上的值,stat_description 指的是来描述该 统计项的含义的。我们来具体看一下一个索引都有哪些统计项:

  • n_leaf_pages:表示该索引的叶子节点占用多少页面。
  • size:表示该索引共占用多少页面。
  • n_diff_pfxNN:表示对应的索引列不重复的值有多少。其中的 NN 长得有点儿怪呀,啥意思呢?

其实 NN 可以被替换为 01、02、03… 这样的数字。比如对于 u_idx_day_status来说:
n_diff_pfx01 表示的是统计 insert_time 这单单一个列不重复的值有多少。
n_diff_pfx02 表示的是统计 insert_time,order_status 这两个列组合起来不重复的值有多少。
n_diff_pfx03 表示的是统计 insert_time,order_status,expire_time 这三个列组合起来不重复的值有多少。
n_diff_pfx04 表示的是统计 key_pare1、key_pare2、expire_time、id 这四个列组合起来不重复的值有多少。
对于普通的二级索引,并不能保证它的索引列值是唯一的,比如对于
idx_order_no 来说,key1 列就可能有很多值重复的记录。此时只有在索引列上加上主键值才可以区分两条索引列值都一样的二级索引记录。
对于主键和唯一二级索引则没有这个问题,它们本身就可以保证索引列值的不重复,所以也不需要再统计一遍在索引列后加上主键值的不重复值有多少。比如 u_idx_day_statu 和 idx_order_no。
在计算某些索引列中包含多少不重复值时,需要对一些叶子节点页面进行采样,sample_size 列就表明了采样的页面数量是多少。
对于有多个列的联合索引来说,采样的页面数量是:
innodb_stats_persistent_sample_pages × 索引列的个数。
在这里插入图片描述
当需要采样的页面数量大于该索引的叶子节点数量的话,就直接采用全表扫描来统计索引列的不重复值数量了。所以大家可以在查询结果中看到不同索引对应的 size 列的值可能是不同的。

5.4.2.3. 定期更新统计数据

随着我们不断的对表进行增删改操作,表中的数据也一直在变化,
innodb_table_stats 和 innodb_index_stats 表里的统计数据也在变化。MySQL 提供了如下两种更新统计数据的方式:
开启 innodb_stats_auto_recalc
系统变量 innodb_stats_auto_recalc 决定着服务器是否自动重新计算统计数据,它的默认值是 ON,也就是该功能默认是开启的。每个表都维护了一个变量, 该变量记录着对该表进行增删改的记录条数,如果发生变动的记录数量超过了表 大小的 10%,并且自动重新计算统计数据的功能是打开的,那么服务器会重新进行一次统计数据的计算,并且更新 innodb_table_stats 和 innodb_index_stats 表。
不过自动重新计算统计数据的过程是异步发生的,也就是即使表中变动的记录数超过了 10%,自动重新计算统计数据也不会立即发生,可能会延迟几秒才会进行计算。

再一次强调,InnoDB 默认是以表为单位来收集和存储统计数据的,我们也可以单独为某个表设置是否自动重新计算统计数的属性,设置方式就是在创建或修改表的时候通过指定 STATS_AUTO_RECALC 属性来指明该表的统计数据存储方式:

CREATE TABLE 表名 (...) Engine=InnoDB, STATS_AUTO_RECALC = (1|0);
ALTER TABLE 表名 Engine=InnoDB, STATS_AUTO_RECALC = (1|0);

当 STATS_AUTO_RECALC=1 时,表明我们想让该表自动重新计算统计数据,
当 STATS_AUTO_RECALC=0 时,表明不想让该表自动重新计算统计数据。如果我们在创建表时未指定 STATS_AUTO_RECALC 属性,那默认采用系统变量 innodb_stats_auto_recalc 的值作为该属性的值。
手动调用 ANALYZE TABLE 语句来更新统计信息
如果 innodb_stats_auto_recalc 系统变量的值为 OFF 的话,我们也可以手动调用 ANALYZE TABLE 语句来重新计算统计数据,比如我们可以这样更新关于 order_exp 表的统计数据:

mysql> ANALYZE TABLE order_exp;

在这里插入图片描述
ANALYZE TABLE 语句会立即重新计算统计数据,也就是这个过程是同步的,在表中索引多或者采样页面特别多时这个过程可能会特别慢最好在业务不是很繁忙 的时候再运行。

5.4.2.4. 手动更新 innodb_table_stats 和 innodb_index_stats 表

其实 innodb_table_stats 和 innodb_index_stats 表就相当于一个普通的表一样,我们能对它们做增删改查操作。这也就意味着我们可以手动更新某个表或者索引的统计数据。比如说我们想把 order_exp 表关于行数的统计数据更改一下可以这么做:
步骤一:更新 innodb_table_stats 表。
步骤二:让 MySQL 查询优化器重新加载我们更改过的数据。
更新完 innodb_table_stats 只是单纯的修改了一个表的数据,需要让 MySQL.

查询优化器重新加载我们更改过的数据,运行下边的命令就可以了:
FLUSH TABLE order_exp

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/164309.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Scalable Exact Inference in Multi-Output Gaussian Processes

Orthogonal Instantaneous Linear Mixing Model TY are m-dimensional summaries,ILMM means ‘Instantaneous Linear Mixing Model’,OILMM means ‘Orthogonal Instantaneous Linear Mixing Model’ 辅助信息 作者未提供代码

年货FPS大作,艾尔莎EA B450M-E和你玩转《使命召唤20》

说到动视旗下的《使命召唤》系列,相信大家都不陌生,它以出色爽快的游戏体验以及精良的画面著称,而且每年一部的更新节奏也是如今为数不多的“年货”游戏之一了。时至今日,该系列已经来到了第20部作品,也就是《使命召唤…

Argo Rollouts结合Service进行Blue-Green部署

删除03 部署04 rootk8s-master01:~/learning-jenkins-cicd/09-argocd-and-rollout/rollout-demos# kubectl delete -f 03-rollouts-with-prometheus-analysis.yaml rootk8s-master01:~/learning-jenkins-cicd/09-argocd-and-rollout/rollout-demos# kubectl apply -f 04-rol…

OceanBase:Zone管理

OceanBase 集群由若干个 Zone 组成。从物理层面来讲,一个 Zone 通常是一个独立的物理部署单元,可以是一个数据中心(IDC)或者云上的一个 Zone(可用区),也可以是一个单独的机架(Rack&a…

AI工具合集

网站:未来百科 | 为发现全球优质AI工具产品而生 (6aiq.com) 如今,AI技术涉及到了很多领域,比如去水印、一键抠图、图像处理、AI图像生成等等。站长之家之前也分享过一些,但是在网上要搜索找到它们还是费一些功夫。 今天发现了一…

第 372 场 LeetCode 周赛题解

A 使三个字符串相等 求三个串的最长公共前缀 class Solution { public:int findMinimumOperations(string s1, string s2, string s3) {int n1 s1.size(), n2 s2.size(), n3 s3.size();int i 0;for (; i < min({n1, n2, n3}); i)if (!(s1[i] s2[i] && s2[i] s…

系列十、你说你做过JVM调优和参数配置,请问如何盘点JVM系统的默认值?

一、JVM的参数类型 1.1、标配参数 java -versionjava -help 1.2、XX参数 1.2.1、Boolean类型 公式&#xff1a;-XX:或者- 某个属性值 表示开启、-表示关闭 # 是否打印GC收集细节 -XX:PrintGCDetails -XX:-PrintGCDetails# 是否使用串行垃圾收集器 -XX:UseSerialGC -XX:-UseS…

Java Web——Web开发介绍

什么是Web开发 Web开发是一种创建和维护全球广域网&#xff08;World Wide Web&#xff09;上的网站和应用的技术。全球广域网也称为万维网(www World Wide Web)&#xff0c;是一个能够通过浏览器访问的互联网上的巨大信息库。 Web开发的目标是创建功能齐全、易于使用和安全的…

C++多线程编程(2):四种线程管理方法

文章首发于我的个人博客&#xff1a;欢迎大佬们来逛逛 文章目录 线程管理get_idsleep_forsleep_untilyield 线程管理 有一个this_thread的名称空间中定义了许多的线程管理方法&#xff1a; get_id&#xff1a;获取当前线程idsleep_for&#xff1a;当前线程休眠一段时间sleep_…

开源更安全? yum源配置/rpm 什么是SSH?

文章目录 1.开放源码有利于系统安全2.yum源配置&#xff0c;这一篇就够了&#xff01;(包括本地&#xff0c;网络&#xff0c;本地共享yum源)3.rpm包是什么4.SSH是什么意思&#xff1f;有什么功能&#xff1f; 1.开放源码有利于系统安全 开放源码有利于系统安全 2.yum源配置…

数据挖掘复盘——apriori

read_csv函数返回的数据类型是Dataframe类型 对于Dataframe类型使用条件表达式 dfdf.loc[df.loc[:,0]2]df: 这是一个DataFrame对象的变量名&#xff0c;表示一个二维的表格型数据结构&#xff0c;类似于电子表格或SQL表。 df.loc[:, 0]: 这是使用DataFrame的.loc属性来进行…

Java调用com组件之jacob

一、背景介绍 现有标准的 win32 com组件&#xff0c;有如下的参数&#xff1a; 属性 值 说明Program IDyinhai.yh_hb_sctrCOM ClassIDCOM ClassName COClass_yh_hb_sctr Interface TypeDual InterfaceInterface NameIyh_hb_sctr 具有一个方法&#xff1a; yh_hb_call( string…

6个系统设计的基本概念

1*Xl9kK7ffgu18IaJ637-cTg.png 简介 这份综合指南将引导你掌握在系统设计中取得成功所需的基本概念。 垂直和水平扩展 1. 垂直扩展 系统扩展的最直接方式是通过垂直扩展。这涉及升级现有服务器&#xff0c;例如增加更多的RAM或更快的CPU。 1*8OAEF45gAfOxvrTUz6hp3w.png 垂直扩…

《向量数据库指南》——亚马逊云科技向量数据库揭秘:点亮数据未来!

在我们讨论亚马逊云科技向量数据库之前,我们必须先搞懂向量数据库。 那么,向量数据库是什么呢?简单来说,向量数据库就是一种专门用于处理和查询向量数据的数据库。与传统数据库以表格形式组织和存储数据不同,向量数据库采用多维数值数组的形式处理和存储数据。它的主要目标…

从多表连接视图对比人大金仓和Oracle

KING BASE 信息时代&#xff0c;数据是驱动业务决策和创新的核心资源。然而&#xff0c;随着数据量的不断增加&#xff0c;有效地处理和整合数据的过程变得愈发复杂。这时&#xff0c;多表连接视图悄然走进数据库世界&#xff0c;不仅能够将多个表中的数据整合在一起&#xff0…

和解电话(匿名电话)/情侣拉黑联系电话/虚拟号/虚拟中间号/拉黑联系项目代码

和解电话&#xff0c;又名匿名电话 使用中间号转接到被叫人&#xff0c;不显示呼叫人号码&#xff0c;类似美团隐私号 呼叫人A->中间号B->被叫人C 演示地址&#xff1a;微信打开(http://sms.test.4php.top/sms/phone) 实现代码如下 <section class"section&q…

Java工具包Hutool框架

Hutool是一个Java基础工具类,对文件、流、加密解密、转码、正则、线程、XML 等 JDK 方法进行封装,组成各种 Util 工具类。官网地址:https://www.hutool.cn/。 添加依赖 <dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artif…

【具身智能评估2】具身视觉语言规划(EVLP)数据集基准汇总

参考论文&#xff1a;Core Challenges in Embodied Vision-Language Planning 论文作者&#xff1a;Jonathan Francis, Nariaki Kitamura, Felix Labelle, Xiaopeng Lu, Ingrid Navarro, Jean Oh 论文原文&#xff1a;https://arxiv.org/abs/2106.13948 论文出处&#xff1a;Jo…

WIFI版本云音响设置教程腾讯云平台版本

文章目录 WIFI版本云音响设置教程腾讯云平台版本一、申请设备三元素1.腾讯云物联网平台2.创建产品3.设置产品参数4.添加设备5.获取三元素 二、设置设备三元素1.打开MQTTConfigTools2.计算MQTT参数3.使用windows电脑的WIFI连接到设备热点4.设置参数 三、腾讯云物联网套件协议使用…

基于鼠群算法优化概率神经网络PNN的分类预测 - 附代码

基于鼠群算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于鼠群算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于鼠群优化的PNN网络5.测试结果6.参考文献7.Matlab代码 摘要&#xff1a;针对PNN神经网络的光滑…