索引选择性是衡量索引效率的关键指标,计算公式为不同值数量除以总行数,结果越接近1,查询性能越高。高选择性列能显著减少数据扫描量,提升查询速度;低选择性字段如性别、状态等重复值多,不适合作为独立索引。在复合索引中,应将选择性高的列放在前面,以提高索引利用率。可通过SELECT COUNT(DISTINCT column_name) / COUNT(*) FROM table_name;估算选择性,指导索引设计。

在MySQL中,索引选择性(Index Selectivity)是衡量索引效率的重要指标,直接影响查询性能。选择性越高,意味着索引列中不同值的数量越多,重复值越少,数据库通过该索引能更精准地定位目标数据,从而提升查询速度。
什么是索引选择性
索引选择性通常用以下公式表示:
选择性 = 不同值的数量 / 总行数
结果范围在 0 到 1 之间。越接近 1,说明列中大部分值都是唯一的,索引效率越高;越接近 0,说明列中存在大量重复值,索引效果较差。
例如:
- 用户表中的 user_id 是主键,每行唯一,选择性为 1,是理想的高选择性列。
- 性别字段只有“男”和“女”,假设总共有10000条记录,不同值数量为2,则选择性为 2/10000 = 0.0002,非常低,不适合作为独立索引使用。
高选择性如何提升查询性能
MySQL优化器在执行查询时会根据统计信息评估使用哪个索引。高选择性索引能显著减少需要扫描的数据页数量。
- 当你执行 WHERE email = 'xxx@example.com',而 email 字段具有高选择性(如唯一索引),MySQL可能只需查找一两个索引节点就定位到数据。
- 如果对低选择性的字段(如 status 状态字段)建立索引,即使命中索引,仍需回表大量匹配行,可能导致优化器直接放弃使用索引,改用全表扫描。
复合索引中的选择性优化
在创建复合索引时,列的顺序很重要。一般建议将选择性高的列放在前面。
例如,有一个订单表,有 status(低选择性)和 created_at(高选择性)两个字段:
- 索引 (created_at, status) 比 (status, created_at) 更有效,因为先通过时间缩小范围,再过滤状态,效率更高。
- 如果把低选择性字段放前面,前导列无法有效剪枝,索引利用率下降。
如何查看索引选择性
可以通过以下SQL估算某列的选择性:
SELECT COUNT(DISTINCT column_name) / COUNT(*) FROM table_name;
例如:
SELECT COUNT(DISTINCT email) / COUNT(*) FROM users;
结果接近1说明适合建索引,远小于1则需谨慎。
基本上就这些。选择性是判断是否创建索引以及如何设计复合索引的关键依据,理解它有助于写出更高效的查询语句和更合理的索引策略。不复杂但容易忽略。










