为查询准备访问路径

没有合适索引时,按某列查找可能需要逐行扫描整表。索引保存能够按其规则搜索的键和记录定位信息,使数据库有机会先缩小候选范围,再取得需要的记录。

索引可以帮助筛选、连接及某些排序工作,但支持哪类条件取决于索引方法、键顺序及运算符。建立在一个字段上的索引,不会让所有引用这张表的查询都自动变快。

多列B树的列顺序也影响实际读取量。对(a, b)索引,a的等值条件通常能先限定连续搜索区域;只有b的条件仍可能使用索引,却未必能少读同样多的索引页。PostgreSQL 18的跳跃扫描还能在a的不同值较少时,重复进行带内部a等值条件的定位,利用后列约束跳过无关区间。因此“没有最左列条件就绝不走索引”和“用到了索引就只读命中项”都过于绝对,仍应核对实际计划。

参考:[1] [2] [5]

优化器仍可能选择扫描

若查询要取出表中很大一部分数据,经过索引再逐个访问表页,可能比顺序扫描更贵。优化器会结合预计返回行数、页面访问与其他成本,比较可用路径。

PostgreSQL的执行计划示例显示,改变筛选范围可能把顺序扫描改成位图或普通索引扫描。EXPLAIN让人看见实际选择;索引已经存在与计划真的使用索引,是两个需要分别验证的事实。

参考:[3] [1]

读取收益伴随写入成本

表的相关内容变化时,系统还要维护索引与数据的一致,因此索引占用额外空间,也增加插入、更新和删除的工作。长期不被使用的索引可能只留下维护负担。

计划选择还依赖统计资料。数据分布改变后,旧统计可能误估收益;PostgreSQL用ANALYZE更新这些信息。索引设计应依据真实查询与数据分布复核,而不是把索引数量当作性能水平。

参考:[1] [4]