原创作者:杨涛涛


MySQL 8.0 推出了histogram,也叫柱状图或者直方图。先来解释下什么叫直方图。

关于直方图

我们知道,在DB中,优化器负责将SQL转换为很多个不同的执行计划,完了从中选择一个最优的来实际执行。但是有时候优化器选择的最终计划有可能随着DB环境的变化不是最优的,这就导致了查询性能不是很好。比如,优化器无法准确的知道每张表的实际行数以及参与过滤条件的列有多少个不同的值。那其实有时候有人就说了,索引不是可以解决这个问题吗?是的,不同类型的索引可以解决这个问题,但是你不能每个列都建索引吧?如果一张表有1000个字段,那全字段索引将会拖死对这张表的写入。而此时,直方图就是相对来说,开销较小的方法。

直方图就是在 MySQL 中为某张表的某些字段提供了一种数值分布的统计信息。比如字段NULL的个数,每个不同值出现的百分比、最大值、最小值等等。如果我们用过了 MySQL 的分析型引擎brighthouse,那对这个概念太熟悉了。

MySQL的直方图有两种,等宽直方图和等高直方图。等宽直方图每个桶(bucket)保存一个值以及这个值累积频率;等高直方图每个桶需要保存不同值的个数,上下限以及累计频率等。MySQL会自动分配用哪种类型的直方图,我们无需参与。

MySQL 定义了一张meta表column_statistics 来存储直方图的定义,每行记录对应一个字段的直方图,以json保存。同时,新增了一个参数histogram_generation_max_mem_size来配置建立直方图内存大小。

不过直方图有以下限制:

1. 不支持几何类型以及json。 2. 不支持加密表和临时表。 3. 不支持列值完全唯一。 4. 需要手工的进行键值分布。

那我们来举个简单的例子说明直方图对查询的效果提升。

举例

表相关定义以及行数信息等:

mysql> show create table t2G
*************************** 1. row ***************************
Table: t2
Create Table: CREATE TABLE `t2` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`rank1` int(11) DEFAULT NULL,
`rank2` int(11) DEFAULT NULL,
`rank3` int(11) DEFAULT NULL,
`log_date` date DEFAULT NULL,PRIMARY KEY (`id`),KEY `idx_rank1` (`rank1`),KEY `idx_log_date` (`log_date`)
) ENGINE=InnoDB AUTO_INCREMENT=49140 DEFAULT CHARSET=utf8mb4
COLLATE=utf8mb4_0900_ai_ci STATS_PERSISTENT=1 STATS_AUTO_RECALC=0
1 row in set (0.00 sec)
mysql> select count(*) from t2;
+----------+
| count(*) |
+----------+
|    30940 |
+----------+
1 row in set (0.00 sec) 

同时对t2克隆了一张表t3

mysql> create table t3 like t2;
Query OK, 0 rows affected (0.13 sec)
mysql> insert into t3 select * from t2;
Query OK, 30940 rows affected (1.94 sec)
Records: 30940 Duplicates: 0 Warnings: 0 

给表t3列rank1和log_date 添加histogram

mysql> analyze table t3 update histogram on rank1,log_date;
+--------+-----------+----------+-----------------------------------------------------+
| Table  | Op        | Msg_type | Msg_text                              |
+--------+-----------+----------+-----------------------------------------------------+
| ytt.t3 | histogram | status   | Histogram statistics created for column 'log_date'. |
| ytt.t3 | histogram | status   | Histogram statistics created for column 'rank1'.    |
+--------+-----------+----------+-----------------------------------------------------+
2 rows in set (0.19 sec)

我们来看看histogram的分布状况

mysql> select json_pretty(histogram)  result from information_schema.column_statistics where table_name = 't3' and column_name = 'log_date'G
*************************** 1. row ***************************
result: {
"buckets": [[
"2018-04-17",
"2018-04-20",
0.01050420168067227,
4],...,[
"2019-04-14","2019-04-16",
1.0,
3]],
"data-type": "date",
"null-values": 0.0,
"collation-id": 8,
"last-updated": "2019-04-17 03:43:01.910185",
"sampling-rate": 1.0,
"histogram-type": "equi-height",
"number-of-buckets-specified": 100
}
1 row in set (0.03 sec)

MySQL自动为这个字段分配了等高直方图,默认为100个桶。

SQL A:

select count(*) from t2/t3 where (rank1 between 1 and 10) and log_date < '2018-09-01';

SQL A的执行结果:

mysql> select count(*) from t2/t3 where (rank1 between 1 and 10) and log_date < '2018-09-01';
+----------+
| count(*) |
+----------+
|     2269 |
+----------+
1 row in set (0.01 sec)

无histogram的执行计划

mysql> explain format=json select count(*) from t2 where (rank1 between 1 and 10) and log_date < '2018-09-01'G
*************************** 1. row ***************************
EXPLAIN: {"query_block": {"select_id": 1,"cost_info": {"query_cost": "2796.11"},"table": {"table_name": "t2","access_type": "range","possible_keys": ["idx_rank1","idx_log_date"],"key": "idx_rank1","used_key_parts": ["rank1"],"key_length": "5","rows_examined_per_scan": 6213,"rows_produced_per_join": 3106,"filtered": "50.00","index_condition": "(`ytt`.`t2`.`rank1` between 1 and 10)","cost_info": {"read_cost": "2485.46","eval_cost": "310.65","prefix_cost": "2796.11","data_read_per_join": "72K"},"used_columns": ["rank1","log_date"],"attached_condition": "(`ytt`.`t2`.`log_date` < '2018-09-01')"}}
}

有histogram的执行计划

mysql> explain format=json select count(*) from t3 where (rank1 between 1 and 10) and log_date < '2018-09-01'G
*************************** 1. row ***************************
EXPLAIN: {"query_block": {"select_id": 1,"cost_info": {"query_cost": "0.71"},"table": {"table_name": "t3","access_type": "range","possible_keys": ["idx_rank1","idx_log_date"],"key": "idx_log_date","used_key_parts": ["log_date"],"key_length": "4","rows_examined_per_scan": 1,"rows_produced_per_join": 1,"filtered": "100.00","index_condition": "(`ytt`.`t3`.`log_date` < '2018-09-01')","cost_info": {"read_cost": "0.61","eval_cost": "0.10","prefix_cost": "0.71","data_read_per_join": "24"},"used_columns": ["rank1","log_date"],"attached_condition": "(`ytt`.`t3`.`rank1` between 1 and 10)"}}
}
1 row in set, 1 warning (0.00 sec)

我们看到两个执行计划的对比,有Histogram的执行计划cost比普通的sql快了好多倍。

上面文字可以看起来比较晦涩,贴上两张图,看起来就很简单了。

无histogram
有histogram

当然,我这里举得例子相对简单,有兴趣的朋友可以更深入学习其他复杂些的例子。

历期文章回顾

爱可生云数据库:新特性解读 | MySQL 8.0 索引特性4-不可见索引

爱可生云数据库:新特性解读 | MySQL 8.0.16 组复制通讯协议的设置

爱可生云数据库:新特性解读 | MySQL 8.0.16 组复制新功能:消息碎片化

爱可生云数据库:新特性解读 | MySQL 8.0 索引特性3 -倒序索引

爱可生云数据库:新特性解读 | MySQL 8.0 新增 HINT 模式

爱可生云数据库:新特性解读 | MySQL 8.0 索引特性2-索引跳跃扫描

爱可生云数据库:新特性解读 | MySQL 8.0 索引特性1-函数索引

爱可生云数据库:新特性解读 | MySQL 8.0 通用表达式

中累计直方图_新特性解读 | MySQL 8.0 直方图相关推荐

  1. c语言 字符串 正序再倒序_新特性解读 | MySQL 8.0 索引特性3 -倒序索引

    原创作者:杨涛涛 我们今天来介绍下 MySQL 8.0 引入的新特性:倒序索引. MySQL长期以来对索引的建立只允许正向asc存储,就算建立了desc,也是忽略掉. 比如对于以下的查询,无法发挥索引 ...

  2. mysql8导入 psc 没有数据_新特性解读 | MySQL 8.0.22 任意格式数据导入

    作者:杨涛涛 资深数据库专家,专研 MySQL 十余年.擅长 MySQL.PostgreSQL.MongoDB 等开源数据库相关的备份恢复.SQL 调优.监控运维.高可用架构设计等.目前任职于爱可生, ...

  3. mysql force index报错_新特性解读 | MySQL 8.0 索引特性4-不可见索引

    MySQL 8.0 实现了索引的隐藏属性.当然这个特性很多商业数据库早就有了,比如ORACLE,在11g中就实现了.我来介绍下这个小特性. 介绍 INVISIBLE INDEX,不可见索引或者叫隐藏索 ...

  4. mysql 8函数索引_新特性解读 | MySQL 8.0 索引特性1-函数索引

    原创作者:杨涛涛 函数索引顾名思义就是加给字段加了函数的索引,这里的函数也可以是表达式.所以也叫表达式索引. MySQL 5.7 推出了虚拟列的功能,MySQL8.0的函数索引内部其实也是依据虚拟列来 ...

  5. concat 不是可以识别的 内置函数名称。_新特性解读 | MySQL 8.0 窗口函数详解

    背景 一直以来,MySQL 只有针对聚合函数的汇总类功能,比如MAX, AVG 等,没有从 SQL 层针对聚合类每组展开处理的功能.不过 MySQL 开放了 UDF 接口,可以用 C 来自己写UDF, ...

  6. 端口如何支持非localhost访问_新特性解读 | MySQL 8.0.19 支持 DNS SRV

    转载自公众号:玩转MySQL 作者:洪斌 MySQL Router 是 InnoDB Cluster 架构的访问入口,在架构部署上,官方给出的建议是 router 与应用端绑定部署,避免 router ...

  7. 新特性解读 | MySQL 8.0 对 limit 的优化

    作者:杨奇龙 网名"北在南方",资深 DBA,主要负责数据库架构设计和运维平台开发工作,擅长数据库性能调优.故障诊断. 本文来源:原创投稿 *爱可生开源社区出品,原创内容未经授权不 ...

  8. mysql applier_新特性解读 | MySQL 8.0.18 有权限控制的复制

    背景 MySQL 8.0.18 以前,从服务器都是在不检查权限的情况下执行复制事务的,这样做是为了能够让主服务器获取所有内容.实际上,这意味着从机完全信任主机.但是,可能存在一些设置,其中更改跨越了主 ...

  9. 新特性解读 | MySQL 8.0 对 GTID 的限制解除

    作者:杨涛涛 资深数据库专家,专研 MySQL 十余年.擅长 MySQL.PostgreSQL.MongoDB 等开源数据库相关的备份恢复.SQL 调优.监控运维.高可用架构设计等.目前任职于爱可生, ...

最新文章

  1. spark on yarn 完全分布式_Spark编程笔记(1)-架构基础与运行原理
  2. pandas打乱行次序
  3. oracle撤销管理的方法,Oracle9i中利用自动撤销管理的优点
  4. jQuery时间轴特效
  5. WPF设置ListBoxItem失去焦点时的背景色
  6. 表面粗糙度的基本评定参数是_表面粗糙度全方位解析,及表面粗糙度对照表
  7. Spring 思维导图,让 Spring 不再难懂(cache篇)
  8. 1190. 反转每对括号间的子串 golang反转字符串
  9. power bi 中计算_Power BI中的期间比较
  10. [爬虫][python][入门][网页源码][百度图片][豆瓣TOP250]
  11. QT + MinGW 中文显示乱码解决方案
  12. Response.Cookie FF
  13. 输入字符数字串输出保存数字串
  14. mysql删除重复记录只保留一条
  15. 大学生心理健康管理系统
  16. python笔记:python中 | ^表示什么意思
  17. webservice接口与HTTP接口
  18. 基于ESXi虚拟服务器搭建
  19. (翻译)赫曼方格如何影响用户视觉
  20. CAN总线学习笔记 | CAN盒测试STM32的CAN中断接收

热门文章

  1. Android艺术探索笔记 - 创建AIDL文件后自动生成的文件分析
  2. java项目之Bank银行代码
  3. 从零开始学keras之多分类问题
  4. 安卓PHP maker汉化,android 百度地图marker添加自定义视图
  5. Spark 配置指南
  6. Typora入门基本教程
  7. python 运行cmd命令失败怎么办_python manage.py runserver命令在cmd命令框中可以正确执行,但是在pycharm的终端中运行就失败了!...
  8. php要懂函数吗,九个你需要知道的PHP函数和功能
  9. java kafka 消费_java利用kafka生产消费消息
  10. 如何启动php程序,如何第一次运行PHP程序?