第25期:索引设计(索引的基数与可选择性)

本文深入探讨了MySQL中索引基数(Cardinality)的概念及其对查询性能的影响。基数是索引中唯一值的预估值,影响查询优化器的选择。较高的基数意味着更好的索引选择性。举例说明了不同数据分布下,如状态类、订单号、日期等字段的索引基数变化,以及如何根据基数调整联合索引以优化查询效率。同时,展示了SQL查询在不同过滤条件下,优化器如何基于基数选择执行计划。文章强调了索引建立应随数据分布变化而调整的重要性。

这篇主要介绍 MySQL 索引的 Cardinality 值(基数)以及索引的可选择性。

索引基数值

索引基数的含义:

由索引中唯一值计算的一个预估值。索引基数值的准确程度直接影响到 MySQL 优化器基于此索引的查询计划是否准确高效。

与索引基数值最为密切的典型场景就是:一条 SQL 在某一时刻执行比较慢,其中较为可能的原因就是当前表记录更新频繁,这条 SQL 执行计划走的索引基数值没及时更新,优化器选择走备用索引或者走全表扫描,从而非最优执行计划,最终执行结果没有达到预期,总体查询时间较慢,这时可能得手工更新索引的基数值。

索引的可选择性:

索引的可选择性好与坏,和索引基数关系非常密切。基数值越高,索引的可选择性越好;相反,基数越低,索引的可选择性越差。优化器优先使用的索引一般选择性都不差,除非没得选,才会走选择性稍差点的索引或者走全表扫描。

影响索引基数值的相关指标:
  1. 表的 sample page 个数, 也就是表样例数据页的个数,这个在之前表样例数据计算中详细讲过。

  2. 表的更新频率,一般来说,当 1/16 的数据页被更新过,就会自动更新索引基数。

  3. 索引列的数据分布程度,比如状态类,订单号,日期等。不同的数据分布,有不同的索引基数。

  4. 手动进行索引基数更新,比如 analyze table、show table status 等。

查看某个索引的基数值,有多种方式:
  1. 直接执行 show index from tablename。

  2. 查询数据字典表 information_schema.statstics。

举例

下面来举例说明索引基数在不同的数据分布场景下的变化以及对优化器的影响。

基础表结构如下:表 ytt_sample 有 7 个字段,5 个索引,其中主键的基数最大,可选择性最好,其他的索引要看数据的分布状况来定。

(localhost:mysqld.sock)|(ytt)>show create table ytt_sample\G
*************************** 1. row ***************************
       Table: ytt_sample
Create Table: CREATE TABLE `ytt_sample` (
  `id` int NOT NULL AUTO_INCREMENT,
  `r1` int DEFAULT NULL,
  `r2` int DEFAULT NULL,
  `r3` int DEFAULT NULL,
  `r4` int DEFAULT NULL,
  `r5` tinyint DEFAULT NULL,
  `r6` date DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_u1` (`r1`,`r2`,`r3`),
  KEY `idx_r4` (`r4`),
  KEY `idx_r5` (`r5`),
  KEY `idx_r6` (`r6`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)

这张表有 100 行记录。


(localhost:mysqld.sock)|(ytt)>select count(*) from ytt_sample;
+----------+
| count(*) |
+----------+
|      100 |
+----------+
1 row in set (0.03 sec)

检索数据字典,查看当前表索引基数排名:


                
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值