Postgres 索引的存在意义就是回答问题
索引的价值在于改变真实查询需要完成的工作,索引了多少列并不是有效的成功指标。一个能直接找到某位客户最新三笔订单的窄 B-tree,可能胜过无法提供所需顺序的宽索引;读取几乎全部行的查询,则可能正确地忽略两者。评估时要把访问方式、排序和返回数据量放在一起,而不是看到索引名称就宣布优化完成。 从需要的结果出发 假设应用要查询某位客户最新三笔订单。customer 的等值条件缩小候选范围,placed_at 降序选择该客户最新记录,再用 id 作为最后决胜键,处理时间戳相同的情况。(customer, placed_at DESC, id DESC) 就表达了这条查询需要的键顺序。每个键都应对应可解释的条件或排序要求,而不是根据列名凭直觉添加。 收益不只是避免全表扫描。有序索引路径可以取得所需的有限结果后就停止,不必先收集该客户全部订单再排序。去掉 LIMIT,或改成返回大部分行后,成本平衡可能变化。因此同一个索引必须结合完整 SQL 和常用参数评价,不能只盯 WHERE 的一个片段,更不能把少量结果的计划当成大规模导出的保证。 WHERE 条件的文本顺序不会定义索引顺序。PostgreSQL 规划逻辑表达式,把 customer 等值写在 AND 前面或后面,不会重排 B-tree。真正相关的是索引方向、空值顺序、前导键限制和最终 ORDER BY。修改查询时应明确核对这些结构属性,而不是套用“列写在前面就能用索引”的笼统规则。 如实读取执行计划 EXPLAIN 展示计划工作,EXPLAIN ANALYZE 会真正执行并报告实际行数和循环次数。查询返回表中大部分数据,尤其需要索引中没有的宽列时,顺序扫描可能是正确选择。这不证明列顺序错误,也不证明索引创建失败。应把它看成优化器在当前条件下选择的访问成本,而不是必须消除的红色标记。 反过来,出现索引名也不证明查询便宜。索引扫描仍可能访问大量条目和堆元组,bitmap 路径可能还要排序,index-only 计划也可能检查堆可见性。结合 actual rows、适用时的 Heap Fetches、缓冲区活动和 Sort 阅读。顶层有 LIMIT 只有在下层也避免了大量多余工作时才真正省事,不能忽略 LIMIT 下面的完整树。 ...