MySQL特性统计直方图(histogram)信息

2760阅读 0评论2018-07-23 dbwatcher
分类:Mysql/postgreSQL

博客文章除注明转载外,均为原创。转载请注明出处。
本文链接地址:http://blog.chinaunix.net/uid-31396856-id-5787793.html

1、介绍
     MySQL 8.0实现了直方图的统计。数据字典表column_statistics储存了相关列值的直方图统计信息,提供列数据分布情况,以用于优化器构建查询执行计划。执行ANALYZE TABLE [table] 命令可以管理相关列的直方图,默认情况下这些信息会被复制到备库。
比如:
ANALYZE TABLE tbl_name UPDATE HISTOGRAM ON col_name [, col_name] WITH N BUCKETS;
ANALYZE TABLE tbl_name DROP HISTOGRAM ON col_name [, col_name];

INFORMATION_SCHEMA.COLUMN_STATISTICS具有以下特征:
该表包含除几何类型(空间数据)和之外的所有数据类型的列的统计信息,保存为JSON类型。
该表数据是持久化的,因此每次服务器启动时都不需要创建列统计信息。
服务器对表执行更新统计信息; 用户不能去更新信息

2、直方图信息
用户无法直接访问column_statistics表,因为它是数据字典的一部分。
通过数据字典表的视图INFORMATION_SCHEMA.COLUMN_STATISTICS可以查询直方图信息。
CREATE TABLE IF NOT EXISTS column_stats (
  database_name VARCHAR(64) NOT NULL,
  table_name VARCHAR(64) NOT NULL,
  column_name VARCHAR(64) NOT NULL,
  histogram JSON NOT NULL,
  PRIMARY KEY (database_name, table_name, column_name)
) ENGINE=InnoDB CHARACTER SET=utf8 COLLATE=utf8_bin
COMMENT="Column statistics";
 
COLUMN_STATISTICS的定义如下:
SCHEMA_NAME, TABLE_NAME, COLUMN_NAME:模式,表和列其统计应用的名称。
HISTOGRAM: JSON描述列统计信息的值,存储的值为直方图信息。
直方图信息统计特性支持所有的数据类型,包括数值类型,字符串,大对象,枚举类型等,也支持生成的列。
直方图对象具有以下键:
(1)buckets:直方图桶数,默认值为100,可以在创建直方图的时候指定。
桶结构取决于直方图类型。直方图有两种类型:等宽直方图(singleton)和登高直方图(equi-height).
对于等宽直方图,存储桶包含两个值:
值1:桶的值。类型取决于列数据类型。
值2:表示值的累积频率的浮点数。例如,.25和.75表示列中25%和75%的值小于或等于桶值。

对于equi-height直方图,存储桶包含四个值:
值1,2:存储桶的低位和高位包含值。类型取决于列数据类型。
值3:表示值的累积频率的浮点数。例如,.25和.75表示列中25%和75%的值小于或等于桶上限值。
值4:从桶较低值到其较高值的范围内基数的数量。

(2)null-values:介于0.0和1.0之间的数字,表示作为SQL NULL值的列值的分布数。如果为0,则该列不包含任何 NULL值。
(3)last-updated:生成直方图时,YYYY-MM-DD HH:MM:SS.hhmmss格式为UTC值。
(4)sampling-rate:介于0.0和1.0之间的数字,表示为创建直方图而采样的数据部分。值为1表示已读取所有数据(无采样)。
(5)histogram-type:直方图类型:
singleton:一个存储桶表示列中的一个值。当列中的不同值的数量小于或等于ANALYZE TABLE 生成直方图的语句中指定的桶数时,将创建此直方图类型。
equi-height:一个桶代表一系列值。当列中的不同值的数量大于ANALYZE TABLE生成直方图的语句中指定的桶的数量时,将创建此直方图类型 。
(6)number-of-buckets-specified:ANALYZE TABLE生成直方图的语句中指定的存储桶数。
(7)data-type:此直方图包含的数据类型。在从持久化存储介质中读取和解析直方图到内存时是必要的。可以是如下类型:int,uint (无符号整数) ,double, decimal,datetime或 string(包括字符和二进制串)。
(8)collation-id:直方图数据的排序规则ID。当data-type值为字符串的时候最有用。其值对应 ID于INFORMATION_SCHEMA.COLLATIONS 表中的列值。

(root@localhost:)[(none)]> SELECT
         TABLE_NAME, COLUMN_NAME,
         HISTOGRAM->>'$."data-type"' AS 'data-type',
         JSON_LENGTH(HISTOGRAM->>'$."buckets"') AS 'bucket-count'
       FROM INFORMATION_SCHEMA.COLUMN_STATISTICS;
+-----------------+-------------+-----------+--------------+
| TABLE_NAME      | COLUMN_NAME | data-type | bucket-count |
+-----------------+-------------+-----------+--------------+
| country         | Population  | int       |          226 |
| city            | Population  | int       |         1024 |
| countrylanguage | Language    | string    |          457 |
+-----------------+-------------+-----------+--------------+

3.直方图的使用说明
优化程序使用直方图统计信息(如果适用),用于收集统计信息的任何数据类型的列。优化程序应用直方图统计信息,以根据列值与常量值的比较的选择性(过滤效果)确定行估计值。
这些形式的谓词符合直方图使用的条件:
col_name= <> != > < > = <= IS NULL
 IS NOT NULL
 BETWEEN AND NOT BETWEEN AND IN([,] ...)
 NOT IN([,] ...)
constant
col_nameconstant
col_nameconstant
col_nameconstant
col_nameconstant
col_nameconstant
col_nameconstant
col_namecol_namecol_nameconstantconstant
col_nameconstantconstant
col_nameconstantconstantcol_nameconstantconstant


例如,这些语句包含符合直方图使用条件的谓词:
SELECT * FROM orders WHERE amount BETWEEN 100.0 AND 300.0;
SELECT * FROM tbl WHERE col1 = 15 AND col2> 100;


与常量值进行比较的要求包括常量函数,例如 ABS()和 FLOOR():
SELECT * FROM tbl WHERE col1

直方图统计对于非索引列也是很重要的。向一个可使用用直方图统计信息的列添加索引也可能有助于优化程序进行行评估。需要考虑:
修改表数据时必须更新索引。
直方图信息按需创建或更新,因此在修改表数据时不会增加任何开销。当表发生数据修改的时候,统计信息过期,直到下次更新为止。

优化器更偏向从直方图统计信息进行评估范围优化。如果优化程序确定范围优化程序适用,则不使用直方图统计信息。

对于已经被索引的列,对于索引的列,可以使用index dive能够获得比较精确的行统计信息。在这种情况下,直方图统计不一定有用,因为index dive可以产生更加准确的信息。

在某些情况下,使用直方图统计信息可能无法改善查询执行; 例如,如果统计数据已过期。如果是这种情况,使用ANALYZE TABLE重新生成直方图统计信息,然后再次运行查询。

或者,要禁用直方图统计信息,请使用 ANALYZE TABLE删除它们。禁用直方图统计信息的另一种方法是关闭系统变量的condition_fanout_filter标志 optimizer_switch(尽管这可能会禁用其他优化):
SET optimizer_switch ='condition_fanout_filter = off';
如果使用直方图统计数据,则使用可以看到生成的效果EXPLAIN。请考虑以下查询,其中没有可用于列的索引 col1:
SELECT * FROM t1 WHERE col1 <24;
如果直方图统计信息表明57%的行 t1满足col1 < 24谓词,即使没有索引也可以进行过滤,并且EXPLAIN在filtered列中显示57.00 。

--The end
上一篇:MySQL用户管理的变化
下一篇:[Howto]使用NBU恢复oracle数据库