图片:雨中等待
在讨论数据库索引的时候,经常会提到“选择性”(selectivity)这个概念。“选择性”是描述列值数据分布情况的一个重要属性。“选择性”和“基数”(cardinality)是两个密不可分的概念。“基数”就是一列中唯一值的数量,对于有唯一约束的列,“基数”等于表的总行数。
怎么计算索引的选择性?
Selectivity of index = cardinality/(number of records) * 100%
注意,公式中记录的数量(number of records)就是一张表的行数。
选择性是什么意思?
上面的公式应该怎么理解?假设表中有Sex(性别)这一列,列值只有两种可能—`Male`(男性)和`Female`(女性),那么,Sex列的基数(cardinality)就是2。如果这张表中有10000条行记录,那么Sex列的索引的选择性就是2/10000 * 100% = 0.02%。
为什么“选择性”对索引很重要,数据库怎么利用“选择性”的?
“选择性”的高低可以衡量列值的可能性,换句话说,在给定的样本集里有多少个不同的值。
我们思考一下,低选择性意味着什么?低选择性意味着列值没有太多变化(或没有太多的可能性)。例如,Sex列的选择性,只有非常低的0.02%,这就意味着,Sex列的列值有很少的不同值。
选择性对数据库索引有什么影响?
数据库的查询优化器会根据索引的“选择性”来判断是否使用索引执行查询。也就是说,你在某列上创建了索引,这不意味着数据库就一定会使用这个索引,因为有时全表扫描是更高效的选择。
什么时候不应该使用数据库索引?
什么时候不应该使用数据库索引?当“选择性”比较低的时候!为什么低选择性的时候不适合使用索引呢?设想一下,现在我们要查询所有女性的名字,由于性别只有男性和女性两种情况,所以女性占比是50%的可能性很大。那我们就假设确实有50%(5000)是女性。如果查找索引的话,数据库为了查找出所有女性就需要访问索引5000次。要知道访问索引也是需要消耗时间和资源的。所以这种情况,直接去做全表扫描可能会更快一些。可以看到,数据库的查询优化器会根据“选择性”的高低来决定使用索引还是直接全表扫描。
“选择性”等于多少才会使用索引?
这个问题很难回答,它因数据库而异。
当然,“选择性”很高时,应该使用索引。例如,我们要查询的某列,其“选择性”是100%,说明该列的列值都是唯一的。这时,如果只查询其中的一行,使用索引是最高效的。同时,这也是执行全表扫描最坏的情形。