2024年9月26日: PostgreSQL 17 发布!
支持的版本:当前 (17) / 16 / 15 / 14 / 13 / 12
开发版本:开发版
不受支持的版本:11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1

11.5. 组合多个索引 #

单个索引扫描只能使用查询子句,这些子句使用索引的列以及其运算符类别的运算符,并且使用AND连接。例如,如果在(a, b)上有一个索引,则查询条件如WHERE a = 5 AND b = 6可以使用索引,但查询如WHERE a = 5 OR b = 6则无法直接使用索引。

幸运的是,PostgreSQL能够组合多个索引(包括同一索引的多重使用)来处理无法通过单个索引扫描实现的情况。系统可以在多个索引扫描之间形成ANDOR条件。例如,查询如WHERE x = 42 OR x = 47 OR x = 53 OR x = 99可以分解成对x上的索引的四个独立扫描,每个扫描使用一个查询子句。然后,将这些扫描的结果进行OR运算以产生结果。另一个例子是,如果我们在xy上分别有索引,则查询如WHERE x = 5 AND y = 6的一种可能的实现方式是,使用每个索引及其相应的查询子句,然后将索引结果进行AND运算以识别结果行。

为了组合多个索引,系统会扫描每个所需的索引,并在内存中准备一个位图,该位图给出报告为匹配该索引条件的表行的位置。然后,根据查询的需要将位图进行AND和OR运算。最后,访问并返回实际的表行。表行按物理顺序访问,因为这是位图的布局方式;这意味着原始索引的任何排序都会丢失,因此如果查询具有ORDER BY子句,则需要单独的排序步骤。由于这个原因,并且因为每个额外的索引扫描都会增加额外的时间,所以计划程序有时会选择使用简单的索引扫描,即使有其他可用的索引也可以使用。

在除最简单的应用程序之外的所有应用程序中,都存在各种可能很有用的索引组合,数据库开发人员必须权衡利弊以决定提供哪些索引。有时多列索引是最佳选择,但有时最好创建单独的索引并依赖索引组合功能。例如,如果您的工作负载包括各种查询,有时仅涉及列x,有时仅涉及列y,有时涉及这两列,则可以选择在xy上创建两个单独的索引,依靠索引组合来处理使用这两列的查询。您也可以在(x, y)上创建一个多列索引。对于涉及这两列的查询,此索引通常比索引组合更有效,但正如第11.3节中所述,对于仅涉及y的查询,它几乎没有用,因此它不应是唯一的索引。多列索引和y上的单独索引的组合将提供合理的性能。对于仅涉及x的查询,可以使用多列索引,尽管它会比仅在x上的索引更大,因此速度也更慢。最后一个选择是创建所有三个索引,但这可能只有在比更新更频繁地搜索表并且所有三种类型的查询都很常见时才合理。如果其中一种查询类型比其他类型不那么常见,则您可能会选择只创建最匹配常见类型的两个索引。

提交更正

如果您在文档中看到任何不正确的内容,与您对特定功能的体验不符,或者需要进一步说明,请使用此表单报告文档问题。