1.什么是Cardinality?

Cardinality中文译名为:基数。
它在数据库中表示的意思就是数据库中某个表的某个列中不重复行的总个数。
例如下表:t

 CREATE TABLE `t` (`a` int(11) NOT NULL,`b` varchar(800) DEFAULT NULL,`c` int(11) NOT NULL,PRIMARY KEY (`a`),KEY `idx_c` (`c`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci+-------+--------------+------+-----+---------+-------+
| Field | Type         | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| a     | int(11)      | NO   | PRI | NULL    |       |
| b     | varchar(800) | YES  |     | NULL    |       |
| c     | int(11)      | NO   | MUL | NULL    |       |
+-------+--------------+------+-----+---------+-------+

其中的数据有:

+----+--------+-----+
| a  | b      | c   |
+----+--------+-----+
|  3 | yanjd3 |  -3 |
|  4 | yanjd4 |  -4 |
|  5 | yanjd5 |  -5 |
|  6 | yanjd6 |  -6 |
|  7 | yanjd6 |  -7 |
|  8 | yanjd6 |  -8 |
|  9 | yanjd6 |  -9 |
| 10 | yanjd6 | -10 |
| 11 | yanjd6 | -11 |
| 12 | yanjd6 | -12 |
| 13 | yanjd6 | -13 |
| 14 | yanjd6 | -14 |
| 15 | yanjd6 | -15 |
| 16 | yanjd6 | -16 |
| 17 | yanjd6 | -17 |
| 18 | yanjd6 | -18 |
| 20 | yanjd6 | -20 |
| 21 | yanjd2 | -21 |
| 22 | yanjd3 | -22 |
| 23 | yanjd4 | -23 |
| 24 | yanjd5 | -24 |
| 25 | yanjd6 | -25 |
| 26 | yanjd6 | -26 |
| 27 | yanjd6 | -27 |
+----+--------+-----+

我们可以看出:
列a的基数为:24
列b的基数为:5
列c的基数为:24

2.如何在Mysql中统计普通列的基数?

显然易见,我们不可能每次都用眼睛看着数来确定某一列的基数。
在MySQL中可以用下面语句来确定某一列的基数:
以前面的表为例,统计出列a的基数:

mysql> select count(distinct a) from t;
+-------------------+
| count(distinct a) |
+-------------------+
|                24 |
+-------------------+
1 row in set (0.00 sec)

统计b列的基数:

mysql> select count(distinct b) from t;
+-------------------+
| count(distinct b) |
+-------------------+
|                 5 |
+-------------------+

统计c列的基数:

mysql> select count(distinct c) from t;
+-------------------+
| count(distinct c) |
+-------------------+
|                24 |
+-------------------+
1 row in set (0.00 sec)

3.基数的用处

关于基数的用处只需记住一点:对于索引列,基数越大,查询效果越好,基数越小,查询效果越差,理想的索引列满足: 基数/实际行=1;

对于索引列,我们可以通过下面语句查看其基数:

mysql> show indexes from t \G;

从这里我们可以看到,对于索引列,数据库会自动对其基数进行统计。

4.InnoDB是怎样为索引列统计基数?

在生产环境中,索引的更新操作可能会非常频繁,如果每次索引发生变化时对其基数进行统计,那么将会给数据库带来很大的负担。
这是不能接受的,所以MySQL的策略是:
1)当表中索引列1/16的数据发生变化时,会对其基数进行统计。
2)stat_modified_counter>2000000000时(如果表中某一行的数据频繁地进行更新,这时表中的数据实际并没有增加,发生变化的还是这一行数据,这种情况下第一种策略就无法生效,所以MySQL设置了一个计时器,用来表示发生变化的次数,当发生变化的次数大于2000000000时进行统计),会对其基数进行统计。

注意:如果一张表非常大,那么实际统计一次基数信息所需要的时间可能会非常长,所以MySQL采用采样的方式进行基数的统计。

InnoDB存储引擎只对8个节点进行采样来统计基数,具体步骤如下:
首先,取得B+树索中节点的数量,记为A;
然后,随机取B+树索引中的8个节点,统计每页不同记录的个数,记为P1,P2,P3…P8;
最后计算出此索引列的基数=(P1+P2+P3+P4…+P8)*A/8

注意:上面获取8个节点的方式是随机!!这就意味着,统计的基数信息每次可能不同,这是正常的现象。

5.动手试一试

还是以上面的表t为例子
首先查看其索引列a的基数:

然后插入数据:

INSERT INTO T (a,b,c) values(28,'yanjd2',-21);
INSERT INTO T (a,b,c) values(29,'yanjd3',-22);
INSERT INTO T (a,b,c) values(30,'yanjd4',-23);
INSERT INTO T (a,b,c) values(31,'yanjd5',-24);
INSERT INTO T (a,b,c) values(32,'yanjd6',-25);
INSERT INTO T (a,b,c) values(33,'yanjd6',-26);
INSERT INTO T (a,b,c) values(34,'yanjd6',-27);

然后,查看其索引基数:

这时发现,其基数统计信息没发生变化啊?? 这可能是统计触发条件没达到的原因。

解决方案:我们可以执行下面语句使mysql主动计算统计信息:

 analyze table t;//主动让mysql计算统计信息

这时可以发现,索引a的基数信息发生变化了。

6.MySQL列Cardinality(基数)相关推荐

  1. mysql基数是什么意思_谈谈MySQL中的基数是啥?

    1基数是啥? 大白话讲:基数指的就是MySQL表中某一列的不同值的数量. 如果这一列是唯一索引,那基数 == 行数. 如果这一列是sex,枚举类型只有男女,那它是基数就是2.Cardinality越高 ...

  2. MySQL中Cardinality值的介绍

    1)         什么是Cardinality 不是所有的查询条件出现的列都需要添加索引.对于什么时候添加B+树索引.一般的经验是,在访问表中很少一部分时使用B+树索引才有意义.对于性别字段.地区 ...

  3. MySQL列的别名 insert into select from

    MySQL列的别名 有时,列的名称是一些表达式,使查询的输出很难理解.要给列一个描述性名称,可以使用列别名. 以下语句说明了如何使用列别名: SELECT [column_1 | expression ...

  4. mysql超长sql查询_超长SQL怎么查询?MySQL列长度限制有哪些 | 学步园

    MySQL字符串的限制长度看似重要性不要,其实和整个MySQL数据库的安全性是息息相关的,很值得我们去深入研究分析.SQL注入攻击一直都在被广泛的讨论,然而人们却忽略了今天我将要介绍的这两个安全隐患, ...

  5. mysql 列合并_mysql 列转行,合并字段的方法(必看)

    数据表: 列转行:利用max(case when then) max---聚合函数 取最大值 (case course when '语文' then score else 0 end) ---判断 a ...

  6. MYSQL 列转行方法

    MYSQL 列转行方法 目标 上周遇到个业务场景,要求把一列中用分隔符连接的数据,通过分隔符转多行,形如: 转为 准备 表结构 CREATE TABLE `t_tag` (`id` int NOT N ...

  7. mysql 分组 列转行,mysql列转行以及年月分组实例

    如下所示: SELECT count(DISTINCT(a.rect_id)) zcount, a.job_dept, DATE_FORMAT(submit_date, '%Y-%m') zsubmi ...

  8. mysql 改列定义_如何更改MySQL列定义?

    要更改MySQL列定义,我们可以在ALTER命令中使用Modify或change子句.让我们首先创建一个表,该表的ID为一列,数据类型为int.我们将使用varchar数据类型修改相同的列名称. 创建 ...

  9. ElasticSearch cardinality基数 算法优化内存开销及HLL算法

    2019独角兽企业重金招聘Python工程师标准>>> cardinality 可用于聚合函数,可计算某个字段的基数,即该字段的distinct值,它基于HLL算法来实现的.HHL会 ...

  10. mysql 列转行union all_MySQL中的列转行 - osc_qheq8wav的个人空间 - OSCHINA - 中文开源技术交流社区...

    mysql中的列转行 在工作中遇到的一个MySQL列转行的统计: 场景 用户访问app时会跳出标签选择页面让用户选择喜欢的标签,在数据库中记录的是数组样式的字符串,数据样式大致如下: id user_ ...

最新文章

  1. vs2010设置boost开发环境
  2. python400集视频教程 百度云-Python自动化测试视频教程【百度云盘下载】
  3. 【PAT乙级】1078 字符串压缩与解压 (20 分)
  4. 期货市场计算机分析指南在线,期货市场计算机分析指南
  5. 人工智能发展史_人工智能发展史:4张图看尽AI重大里程碑
  6. 华为海思总裁致信员工:多年备胎一夜转正 挽狂澜于既倒
  7. SAP License:SAP信用控制
  8. 利用skipList(跳表)来实现排序(待补充)
  9. [深度学习] Python人脸识别库face_recognition使用教程
  10. 本周大新闻|苹果首款MR没有主打卖点;Meta认为AI是AR OS的基础
  11. 北理工嵩天Python学习笔记
  12. 树莓派 Raspberry 4B 刷机、上网、录音外设、文件传输、电脑投屏问题汇总
  13. 直流电机笔记1-串并励电机特性
  14. 【速记】Android让View的显示超出父容器
  15. 可逆计算机系统设计,计算机控制断续电流可逆系统的动态设计与仿真研究
  16. (转) 阿拉贡的故事
  17. Google 面试题 | 判断字符串是否可由重复子字符串组成
  18. 自然数与有理数的双射函数
  19. 计算机折旧的常用会计函数,Excel财务函数:AMORLINC每个结算期间的折旧值-excel技巧-电脑技巧收藏家...
  20. 数据采集之用户行为日志采集

热门文章

  1. 英特尔cpu与主板芯片组对应关系(包含12代)
  2. 面向对象之魔术方法_call
  3. 关于 IE 浏览器打开时速度过慢的问题
  4. linux audit 服务,linux 的 audit 服務
  5. (中英)作文 —— 标题与小标题
  6. 嵌入式测试 模拟共享单车
  7. QSPI FLASH与SD卡同时支持fatfs文件系统
  8. 2022年湖南省基金从业资格(私募股权投资基金基础知识)练习题及答案
  9. 提高多表关联数据查询效率
  10. sklearn笔记19 随机森林和决策树的比较