对于PostgreSQL,我希望在三列A, B, C
上使用复合索引。B
是created_at
的日期时间,偶尔我可能会在没有B
的情况下查询。
如果我在(A, B, C)
上复合索引,然后在A
和C
上查询条件,而不是在B
上查询,会发生什么?(也就是说,A
和C
,但希望它在所有时间内,而不仅仅是某个特定的时间范围?)
Postgres是否足够聪明,仍然使用(A, B, C)
复合索引,只是跳过B?
Postgres可以在多列B树索引中使用非前导列,但效率要低得多。
如果第一列是非常有选择性的(每个A
只有几行),那么您几乎不会注意到性能的差异,因为任何一种访问方法都很便宜。性能命中率随着每个A
的行数而增长。
对于您描述的情况,我建议在(A, C, B)
或(C, A, B)
上创建索引。确保B
排在最后。或者从索引中完全删除B
。或者使用B
为用例创建另一个索引。通过这种方式,您可以在(A, B, C)
和(A, C)
上获得最佳查询性能。
与索引中的列序列不同,查询中的谓词序列无关紧要。
我们已经在dba上对此进行了详细讨论。SE:
- PostgreSQL中的索引工作
请注意,对于当前的情况,无论您是使用A, C
还是C, A
进行引导,都无关紧要:
- 多列索引和性能
还有一些其他考虑因素,但你的问题并没有所有相关的细节。
- 复合索引是否也适用于对第一个字段的查询
是的。
我做了一个快速检查,通过对一个查询进行EXPLAIN,该查询具有索引第一列和第三列的条件。它确实输出了将对该索引进行位图索引扫描,并提到了索引条件中的第一列和第三列。
(在9.3.5测试)