单个索引扫描只能使用索引列及其操作符类中的操作符,并且使用 AND
连接的查询子句。 例如,如果索引在 (a, b)
上,则类似 WHERE a = 5 AND b = 6
的查询条件可以使用该索引,但是类似 WHERE a = 5 OR b = 6
的查询不能直接使用该索引。
幸运的是,PostgreSQL 具有组合多个索引(包括多次使用同一个索引)的能力,以处理单个索引扫描无法实现的情况。 系统可以在多个索引扫描之间形成 AND
和 OR
条件。 例如,像 WHERE x = 42 OR x = 47 OR x = 53 OR x = 99
这样的查询可以分解为对 x
索引的四个单独扫描,每个扫描使用一个查询子句。 然后将这些扫描的结果进行 OR 运算以产生结果。 另一个例子是,如果我们分别在 x
和 y
上有单独的索引,那么像 WHERE x = 5 AND y = 6
这样的查询的一种可能的实现方式是使用每个索引及其相应的查询子句,然后将索引结果进行 AND 运算以识别结果行。
要组合多个索引,系统会扫描每个所需的索引,并在内存中准备一个位图,该位图给出表中与该索引条件匹配的行的位置。 然后根据查询的需要将位图进行 AND 和 OR 运算。 最后,访问并返回实际的表行。 表行按物理顺序访问,因为这是位图的布局方式;这意味着原始索引的任何顺序都会丢失,因此如果查询具有 ORDER BY
子句,则需要单独的排序步骤。 因此,并且因为每次额外的索引扫描都会增加额外的时间,所以计划器有时会选择使用简单的索引扫描,即使有其他索引可用,也可以使用它们。
在所有但最简单的应用程序中,可能有各种有用的索引组合,数据库开发人员必须进行权衡以决定提供哪些索引。 有时多列索引是最好的,但有时创建单独的索引并依靠索引组合功能更好。 例如,如果您的工作负载包含有时仅涉及列 x
,有时仅涉及列 y
,有时同时涉及这两列的混合查询,则可以选择在 x
和 y
上创建两个单独的索引,依靠索引组合来处理使用两列的查询。 您也可以在 (x, y)
上创建多列索引。 对于涉及两列的查询,此索引通常比索引组合更有效,但是正如第 11.3 节中所讨论的,对于仅涉及 y
的查询几乎无用,因此不应是唯一的索引。 多列索引和 y
上的单独索引的组合将很好地服务。 对于仅涉及 x
的查询,可以使用多列索引,尽管它会比单独的 x
索引更大,因此速度更慢。 最后一种选择是创建所有三个索引,但这可能只有在表被搜索的频率远高于更新频率,并且所有三种类型的查询都很常见时才合理。 如果其中一种类型的查询比其他类型少得多,则您可能会选择仅创建最适合常见类型的两个索引。
如果您在文档中发现任何不正确的内容,与您使用特定功能的经验不符,或需要进一步澄清,请使用此表单报告文档问题。