前缀索引和索引的选择性

有时候为了提升索引的性能,同时也节省索引空间,可以只对字段的前一部分字符进行索引,这样做的缺点是,会降低索引的选择性

索引的选择性是指,不重复的索引值(也称为基数,cardinality)和数据表的记录总数(#T)的比值,范围从 1/#T 到 1 之间。

  • 索引的选择性越高则查询效率越高,因为选择性高的索引可以让 MySQL 在查找时过滤掉更多的行。

  • 唯一索引的选择性是 1,这是最好的索引选择性,性能也是最好的。

前缀索引是一种能使索引更小、更快的有效办法,但它也有缺点:MySQL 无法使用前缀索引做 ORDER BY 和 GROUP BY 操作,也无法使用前缀索引做覆盖扫描对于 BLOB、TEXT 或者很长的 VARCHAR 类型的列,必须使用前缀索引,因为 MySQL 并不支持对这些列的完整内容进行索引。

建立前缀索引的关键点在于,既要选择足够长的前缀以保证较高的选择性,同时又不能太长(以便节约空间)。前缀应该足够长,以使得前缀索引的选择性接近于索引整列。换句话说,前缀的“基数”应该接近于完整列的“基数”。

实验

数据准备

CREATE TABLE city_demo
(
    city VARCHAR(50) NOT NULL
);

INSERT INTO city_demo SELECT city FROM city;

--- 重复5次
INSERT INTO city_demo SELECT * FROM city_demo;
--- 

UPDATE city_demo
SET city = (SELECT city FROM city ORDER BY RAND() LIMIT 1);

分析表中数据,找到常见的城市列表

找出分布近似的前缀

查找到最频繁出现的城市前缀,先从 3 个前缀字母开始:

增加前缀长度,直到这个前缀的选择性接近完整列的选择性。经过实验后发现,前缀长度为 7 时比较合适(长度为 8 的前缀与长度为 7 的前缀没有任何变化):

计算列的选择性

计算合适的前缀长度的另外一个办法就是计算完整列的选择性,并使前缀的选择性接近完整列的选择性。

创建索引

最后更新于