深入理解MySQL8.0直方图
墨墨导读:MySQL 8.0 新功能直方图,继承于Oracle ,MairaDB的实现方式。本文从MySQL角度解释,直方图是什么。
MySQL 8.0 新功能直方图,继承于Oracle ,MairaDB的实现方式。
那下面从MySQL角度认识下,直方图是什么。先看下官方直方图的实现方式。
从上图上可以看到原来是ANALYZE命令。先了解一下MySQL里 ANALYZE命令到底有什么用。
ANALYZE
在MySQL里提交一条查询SQL语句时,优化器会选在一个最优的执行方案,并用最小的代价去执行语句。在数据库里面,扫描行数是影响执行代价的因素之一。扫描的行数越少,意味着资源资源越少,扫描行数是怎么判断,是通过索引的基数来得到值和row。
mysql>SHOW INDEX FROM table_name
执行计划里出现的Cardinality(基数)字段,是非常重要的:
基数计算是采样统计,如果把整张表取出来一行行统计,虽然可以得到精确的结果,但是代价太高。采样统计的时候InnoDB 默认会选择 N 个数据页,统计这些页面上的不同值,得到一个平均值,然后乘以这个索引的页面数,就得到了这个索引的基数。而数据表是会持续更新的,索引统计信息也不会固定不变。所以,当变更的数据行数超过 1/M 的时候,会自动触发重新做一次索引统计。
基数很容易不准,除了基数优化器还要判断,执行这个语句本身要扫描多少rows预计扫描行数。
因为统计信息不对,cardinality大大少于数据的实际散列程度,那么索引就有可能失效。
下面看看基数变化的情况:
1. 第一次创建表导入数
2.第二次把表drop掉,导入数据
在这种情况下就会使用analyze table 命令2次
上面是2次,ANALYZE TABLE命令进行修复索引。在不停的浮动。
分析表通过对每个索引树执行随机潜水并相应地更新索引基数估计值来确定索引基数,所以这个值也不是100%准确。
ANALYZE TABLE的作用:
统计索引分布信息。
对于 MyISAM 表,相当于执行了一次 myisamchk --analyze
支持 InnoDB.NDB.MyISAM 等存储引擎,但不支持视图(view)
执行时,会对表加上读锁(read lock)
该操作会记录binlog,可以在analyze和table之间添加关键字local取消写入
ANALYZE TABLE风险:
analyze table的需要扫描的page代价粗略估算公式:sample_pages * 索引数 * 表分区数。
因此,索引数量较多,或者表分区数量较多时,可能会比较费时,要评估代价,并默认只在负载低谷时执行。
如果某个表上当前有慢SQL,此时执行analyze table,则该表后续的查询均会处于waiting for table flush的状态,严重的话会影响业务,因此执行前必须先检查有无慢查询。
直方图
通过ANALYZE操作了解到,在数据库中查询优化所需的指标抽取方式。有时候,查询优化器会走不到最优的执行计划,导致花费了更多不必要的时间。直方图就是解决这样的问题.
直方图能近似获得一列的数据分布情况,从而让数据库知道它含有哪些数据。将数据分到了一系列的buckets中去。MySQL会自动将数据划到不同的buckets中,也会自动决定创建哪种类型的直方图。
1)从代码实现中,MySQL支持了两种:等宽直方图(singleton).等高直方图(equi-height)。
2)两个直方图区别在于equi-height 多了 下限和上限的指标。
3)选择直方图判断逻辑是:如果指定的桶数大于或等于桶数
对于不同的值,创建一个单例直方图。否则创建一个等高直方图。
直方图命令
1)创建命令
ANALYZE TABLE employees01 UPDATE HISTOGRAM ON emp_no WITH 32 BUCKETS;
2)删除命令
ANALYZE TABLE employees01 DROP HISTOGRAM ON emp_no ;
3)查询命令
统计直方图的信息存储在数据字典表"column_statistcs"中,可以通过视图information_schema.COLUMN_STATISTICS访问,直方图以灵活的JSON的格式存储,buckets方式保存,默认是100。
SELECT * FROM INFORMATION_SCHEMA.COLUMN_STATISTICS \G
SELECT HISTOGRAM->>'$."sampling-rate"' FROM INFORMATION_SCHEMA.COLUMN_STATISTICS WHERE TABLE_NAME = "employees01" AND COLUMN_NAME = "emp_no";
采样率值为1意味着来自emp_no列的大约100%的数据被读入内存以生成直方图统计信息。
4)相关参数
histogram_generation_max_mem_size:
备注:用于生成直方图统计信息的最大可用内存量。
5)注意事项
直方图限制:
加密表(为了避免在统计数据中暴露数据)或临时表不支持生成直方图。
直方图生成适用于除几何类型(空间数据)和JSON之外的所有数据类型的列。
可以为存储的和虚拟生成的列生成直方图。
不能为单列惟一索引所覆盖的列生成直方图。
分析表可以使用InnoDB.NDB和MyISAM表
innodb_read_only 需要关闭
information_schema_stats_expiry系统变量定义缓存表统计信息过期之前的时间段
分析表支持分区表
分析表从表定义缓存中删除需要刷新锁的表。如果有长时间运行的语句或事务仍然使用该表,则后续的语句和事务必须等待这些操作完成,然后才能释放刷新锁。
直方图受DDL语句的影响:
删除被删除表中列的直方图。
DROP DATABASE删除被删除数据库中任何表的直方图,因为该语句删除了数据库中的所有表。
重命名表不会移除直方图。相反,它将重命名重命名表的直方图,使之与新表名相关联。
删除或修改列的ALTER TABLE语句删除该列的直方图。
ALTER TABLE……转换为字符集将删除字符列的直方图,因为它们会受到字符集更改的影响。非字符列的直方图不受影响。
其他:
MySQL 8.0.19中,InnoDB存储引擎为存储在InnoDB表中的数据提供了自己的采样实现。当存储引擎不提供自己的存储引擎时,MySQL使用的默认采样实现需要全表扫描,这对于大型表来说代价很高。InnoDB抽样实现通过避免全表扫描提高了抽样性能。
sampled_pages_read和sampled_pages_skip INNODB_METRICS计数器可用于监视InnoDB数据页的采样。
计算公式如下:
sampling rate = sampled_page_read/(sampled_pages_read + sampled_pages_skipped)
通过以下方式确认INNODB_METRICS信息:
mysql> SET GLOBAL innodb_monitor_enable = 'sampled%';
Query OK, 0 rows affected (0.00 sec)mysql> SELECT NAME, COUNT FROM INNODB_METRICS WHERE NAME LIKE 'sampled%'\G
*************************** 1. row ***************************NAME: sampled_pages_read
COUNT: 342
*************************** 2. row ***************************NAME: sampled_pages_skipped
COUNT: 0
2 rows in set (0.00 sec)
基于抽样计数器数据的抽样率大致与INFORMATION_SCHEMA的柱状图列中的抽样率值相同。
测试
1)有无直方图的情况下对比。确实性能提升很多,特别是filtered 和rows 明显有变化。
2)OPTIMIZER_TRACE
mysql> SET OPTIMIZER_TRACE = "enabled=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> explain select * from employees where birth_date>'1964-02-01';
+----+-------------+-----------+------------+-------+---------------+--------------+---------+------+-------+----------+-----------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-----------+------------+-------+---------------+--------------+---------+------+-------+----------+-----------------------+
| 1 | SIMPLE | employees | NULL | range | idx_dt_birth | idx_dt_birth | 3 | NULL | 44288 | 100.00 | Using index condition |
+----+-------------+-----------+------------+-------+---------------+--------------+---------+------+-------+----------+-----------------------+
mysql> SELECT * FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE\G;
备注:mysql服务重新启动之后执行计划不选择直方图,走的是全表扫描,需要官方优化。
总结
按照简单测试用例,大概评估下来,直方图的性能可能提升2倍~3倍。但这对于大数量的访问而言。还有直方图因为需要额外的内存消耗,需要对环境和数据量有效的评估。MySQL 8.0 目前实现的直方图还只是提供了一些基础的功能,执行计划不准确的时候,可以大胆的尝试。
希望官方继续完善。
墨天轮原文链接:https://www.modb.pro/db/27403(复制到浏览器中打开或者点击“阅读原文”)
推荐阅读:144页!分享珍藏已久的数据库技术年刊
数据和云
ID:OraNews
如有收获,请划至底部,点击“在看”,谢谢!
点击下图查看更多 ↓
云和恩墨大讲堂 | 一个分享交流的地方
长按,识别二维码,加入万人交流社群
请备注:云和恩墨大讲堂
点个“在看”
你的喜欢会被看到❤
深入理解MySQL8.0直方图相关推荐
- mysql8.0 直方图_MySQL创建横向直方图
备注:测试数据库版本为MySQL 8.0 如需要scott用户下建表及录入数据语句,可参考: scott建表及录入数据sql脚本 一.需求 使用SQL生成横向延伸的直方图. 例如,采用横向直方图显示每 ...
- MySQL8.0 · 优化器新特性 · Cost Model, 直方图及优化器开销优化
2019独角兽企业重金招聘Python工程师标准>>> MySQL当前已经发布到MySQL8.0版本,在新的版本中,可以看到MySQL之前被人诟病的优化器部分做了很多的改动,由于笔者 ...
- oracle 几个字段中某个字段大于0其他字段不再进行统计?_如何深入理解MySQL 8.0直方图?...
MySQL8.0 新功能直方图,继承于Oracle ,MairaDB的实现方式. 那下面从mysql角度认识下,直方图是什么.先看下官方直方图的实现方式. 从上图上可以看到原来是ANALYZE命令.先 ...
- mysql8.0默认引擎是什么_MySQL8.0新特性【转】
Server层,选项持久化 mysql> show variables like '%max_connections%';+------------------------+-------+ | ...
- 赶紧看一下mysql8.0版本的新特性,你的数据库是不是该升级了
这里写目录标题 前言 mysql8.0的新特性 1.账户安全 2.优化器索引 2.1.隐藏索引(invisible) 2.2.降序索引 2.3.函数索引 3.SQL语句增强 4.新增数据分析函数 5. ...
- MySQL8.0.17 - 初探 Clone Plugin
MySQL8.0.17推出了一个重量级的功能:clone plugin.允许用户可以将当前实例进行本地或者远程的clone.这在某些场景尤其想快速搭建复制备份或者在group replication里 ...
- mysql8.0.19解压版_MySQL8.0解压版配置步骤及具体流程
近半年,因为个人原因,所以内容都搁置了,真是不好意思,所幸还是想继续学习,并且和大家一起成长,所以还是决定继续坚持更文. 又过半年时间,之前和大家分享过MySQL 5.7的免安装方法,现在再和大家说一 ...
- mysql8连接java_JAVA连接MYSQL8.0问题
title: java连接mysql8.0问题 date: 2018-07-08 19:27:38 updated: tags: description: keywords: comments: im ...
- MySQL8.0密码找回与权限刷新
开发日志: 想必大多数开发人员都有外包经验,遇到比较悲催的情况就是,出差忘记带公司电脑,幸幸苦苦,好不容易出差回来,结果发现把公司电脑MySQL密码忘记了.直接破防!!!为了生活,只好老老实实的百度寻 ...
最新文章
- Flink从入门到精通100篇(一)-如何在Mac 上搭建 Flink环境并做简单测试
- python函数可以作为容器对象吗_正确理解Python函数是第一类对象
- ASP.NET 常见参考项目的 UI、BLL 、Model 、 DAL 分析
- 在html标签中写三元运算符,如何在剃须刀中使用三元运算符(特别是在HTML属性上)?...
- python 面向对象_多态、内置方法、反射
- IP地址 网络地址 主机地址
- 计算机二级vb电子书教程,计算机二级VB教程
- 高效办公|用一套键鼠控制两台电脑解决方案
- 06.【Axure 10 】Mac系统软件汉化
- hashcode值相同的字符串
- dlna android电视,DLNA推送安卓手机投屏电视
- GitHub开源项目学习 电商系统Mall (一) Mall简介
- siblings()用法
- vue修改http请求头_vue-resouce设置请求头的三种方法
- Java入坑指南,学Java需要具备哪些前提条件?
- 操作系统 -- 哲学家就餐问题
- java二进制算法教程_关于JAVA入门二进制课程的笔记
- 贪心算法(一)假背包问题,圣诞老人的礼物
- MySQL必知必会-23MySQL全球化和本地化
- Redis入门教程讲解
热门文章
- 流行的编程语言,Audiophile Linux发行版,GNU,Bash,Raspberry PI,DevOps,GIMP等
- ffmpeg开源工具的使用_如何使用开源工具和最佳实践提高在线隐私
- VSCode自定义代码片段5——HTML元素结构
- Bootstrap 编译版文件结构
- 一.路径规划---二维路径规划仿真实现-gmapping+amcl+map_server+move_base
- ROS笔记(3) Melodic 的安装和配置
- 已编辑好的mysql_安装好的mysql改变数据库文件位置
- 上海教育系统计算机职称考试报名,2008年第二季度上海市教育系统职称计算机考试报名的通知...
- Avro从入门到入土
- C#学习笔记_12_枚举结构体