直接回答:选择性 = 列的 distinct 值数 / 总行数,越接近 1 选择性越高。高选择性列(手机号、订单号)走索引能精确定位少数行;低选择性列(性别、布尔标志、状态枚举)单独建索引通常没用——查"状态=活跃"命中 50% 的行,优化器一算:索引扫描要回表 50 万次随机 I/O,还不如顺序扫全表。更糟的是索引占空间、拖慢写入,纯负资产。

展开解析:但低选择性列不是绝对无缘索引,关键是组合WHERE 状态='待处理' AND 创建时间>... 中待处理订单可能只占 1%,组合索引(状态, 创建时间)让低选择性列当等值前缀照样高效;部分索引(PG 的 CREATE INDEX ... WHERE 状态='待处理')只给少数派建索引,又小又快;覆盖索引让查询不回表,低选择性也能容忍。判断工具:看执行计划里估计行数与实际行数的偏差,选择性差的列上统计信息不准(PG 可调 statistics target),优化器容易误判。写入放大也要算账:每条 INSERT/UPDATE 都要维护全部索引,10 个索引的表写入成本可观——索引是拿写和存储换读的权衡,不是免费的午餐。

追问方向:联合索引的最左前缀原则?为什么范围列放组合索引末尾?索引下推(ICP)解决什么?

(约 440 字)