文档章节

数据库索引和选择性的关系

五仁道长
 五仁道长
发布于 2016/05/20 16:55
字数 810
阅读 858
收藏 22

图片:雨中等待

在讨论数据库索引的时候,经常会提到“选择性”(selectivity)这个概念。“选择性”是描述列值数据分布情况的一个重要属性。“选择性”和“基数”(cardinality)是两个密不可分的概念。“基数”就是一列中唯一值的数量,对于有唯一约束的列,“基数”等于表的总行数。

怎么计算索引的选择性?

选择性  =  基数/总行数 * 100%

选择性是什么意思?

上面的公式应该怎么理解?假设表中有Sex(性别)这一列,列值只有两种可能—`Male`(男性)和`Female`(女性),那么,Sex列的基数(cardinality)就是2。如果这张表中有10000条行记录,那么Sex列的索引的选择性就是2/10000 * 100% = 0.02%。

为什么“选择性”对索引很重要,数据库怎么利用“选择性”的?

“选择性”的高低可以衡量列值的可能性,换句话说,在给定的样本集里有多少个不同的值。

我们思考一下,低选择性意味着什么?低选择性意味着列值没有太多变化(或没有太多的可能性)。例如,Sex列的选择性,只有非常低的0.02%,这就意味着,Sex列的列值有很少的不同值。

选择性对数据库索引有什么影响?

数据库的查询优化器会根据索引的“选择性”来判断是否使用索引执行查询。也就是说,你在某列上创建了索引,这不意味着数据库就一定会使用这个索引,因为有时全表扫描是更高效的选择。

什么时候不应该使用数据库索引?

什么时候不应该使用数据库索引?当“选择性”比较低的时候!为什么低选择性的时候不适合使用索引呢?设想一下,现在我们要查询所有女性的名字,由于性别只有男性和女性两种情况,所以女性占比是50%的可能性很大。那我们就假设确实有50%(5000)是女性。如果查找索引的话,数据库为了查找出所有女性就需要访问索引5000次。要知道访问索引也是需要消耗时间和资源的。所以这种情况,直接去做全表扫描可能会更快一些。可以看到,数据库的查询优化器会根据“选择性”的高低来决定使用索引还是直接全表扫描。

“选择性”等于多少才会使用索引?

这个问题很难回答,它因数据库而异。

当然,“选择性”很高时,应该使用索引。例如,我们要查询的某列,其“选择性”是100%,说明该列的列值都是唯一的。这时,如果只查询其中的一行,使用索引是最高效的。同时,这也是执行全表扫描最坏的情形。

 

 

相关阅读:

    《数据库索引的工作原理》

    《全表扫描!你的数据库有点弱智》

© 著作权归作者所有

上一篇: 大O分析法
下一篇: 理解数据库索引
五仁道长
粉丝 25
博文 26
码字总数 28490
作品 0
朝阳
程序员
私信 提问
唯一索引与主键索引的比较

唯一索引与主键索引的比较 唯一索引 唯一索引不允许两行具有相同的索引值。 如果现有数据中存在重复的键值,则大多数数据库都不允许将新创建的唯一索引与表一起保 存。当新数据将使表中的键值...

法斗斗
2016/05/18
90
0
PostgreSQL 当有多个索引可选时,优化器如何选择

标签 PostgreSQL , 索引 , 复合索引 , 选择 , 成本 , 优化器 背景 当一个表有很多索引时,并且一个QUERY可以使用到其中的多个索引时,数据库会如何做出选择?最终选择哪个,或者哪几个索引呢...

德哥
04/14
0
0
sql server中使用组合索引需要注意的地方

1、索引应该建在选择性高的字段上(键值唯一的记录数/总记录条数),选择性越高索引的效果越好、价值越大,唯一索引的选择性最高; 2、组合索引中字段的顺序,选择性越高的字段排在最前面;如...

学习也休闲
2015/09/09
560
0
PostgreSQL 设计优化case - 大宽表任意字段组合查询索引如何选择(btree, gin, rum) - (含单个索引列数超过32列的方法)

标签 PostgreSQL , adhoc查询 , 大宽表 , 任意字段组合查询 , 索引 , btree , gin , rum 背景 大宽表,任意字段组合查询,透视。是实时分析系统中的常见需求: 1、实时写入。 2、实时任意字段...

德哥
04/14
0
0
MySQL索引背后的数据结构及算法原理

摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题。特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,...

asdf08442a
2017/12/26
0
0

没有更多内容

加载失败,请刷新页面

加载更多

lua字符串和时间戳相互转换

1. 时间戳转成格式化字符串 直接利用函数os.date()将时间戳转化成格式化字符串.```local timestamp = 1561636137;local strDate = os.date("%Y/%m/%d %H:%M:%S", timestamp)print("strD......

书香神
18分钟前
0
0
代码规范

代码格式化 安装vscode插件:Prettier - Code formatter 格式化配置:将下列配置写入到vscode的settings.json文件 (遵照代码格式化) "prettier.disableLanguages": ["vue"], "prettier.......

TreeZhou0511
今天
3
0
python实现人工神经网络的一个例子

人工神经网络已经有无数的开源框架,比如tensorflow,caffe等,可以直接用。但最近需要做一个小样例,把基本思想讲一讲,因此自己写了一个demo,以供参考。 下面直接上代码,代码中有注释,比...

propagator
今天
4
0
远程dubugger

1、在tomcat的bin下/data/project/XXX/apache-tomcat-8.5.23/bin 在catalina.bat文件中新增如下即可 JAVA_OPTS="-Xmx1024m -Xms1024m -agentlib:jdwp=transport=dt_socket,server=y,suspend......

一只小青蛙
今天
1
0
jemter 连接MySQL

jemter 连接MySQL 点击测试计划,测试计划最后”添加目录或jar包到ClassPath“,点击浏览,添加mysql-connector.jar mysql-connector.jar的下载地址: https://mvnrepository.com/artifact/my...

xiaobai1315
今天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部