9.3 9.4 9.5 9.6 10 11 12 13 14 15 16 17 Current(18)
PostgreSQL中文社区 问题报告 纠错本页面

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上索引扫描,每一个扫描使用其中一个条件。这些查询的结果将被“或”起来形成最后的结果。另一个例子是如果我们在xy上都有独立的索引,WHERE x = 5 AND y = 6这样的查询的一种可能的实现方式就是分别使用两个索引配合相应的条件,然后将结果“与”起来得到最后的结果行。

为了组合多个索引,系统扫描每一个所需的索引并在内存中准备一个位图用于指示表中符合索引条件的行的位置。然后这些位图会被根据查询的需要“与”和“或”起来。最后,实际的表行将被访问并返回。表行将被以物理顺序访问,因为位图就是以这种顺序布局的。这意味着原始索引中的任何排序都会被丢失,并且如果存在一个ORDER BY子句就需要一个单独的排序步骤。由于这个原因以及每一个附加的索引都需要额外的时间,即使有额外的索引可用,规划器有时也会选择使用单一索引扫描。

在除最简单的应用之外,可能会有各种组合的索引是有用的,数据库开发人员必须进行权衡以决定提供哪些索引。有时多列索引是最佳选择,但有时创建单独的索引并依赖索引组合特性更好。例如,如果您的工作负载包括一组查询,有时只涉及列x,有时只涉及列y,有时涉及两个列,您可能会选择在xy上创建两个单独的索引,依赖索引组合来处理使用两个列的查询。您也可以在(x, y)上创建一个多列索引。这个索引通常会比索引组合对于涉及两个列的查询更有效,但正如在第 11.3 节中讨论的那样,它对于仅涉及y的查询的用处较小。具体有多有用将取决于B-tree索引跳过扫描优化的有效性;如果x的不同值不超过几百个,跳过扫描将使对特定y值的搜索执行得相当高效。在(x, y)上的多列索引和在y上的单独索引的组合也可能表现得相当不错。对于仅涉及x的查询,可以使用多列索引,尽管它会比单独的x索引更大,因此速度更慢。最后的选择是创建三个索引,但这可能只有在表的搜索频率远高于更新频率,并且三种类型的查询都很常见时才合理。如果某种类型的查询远不如其他类型常见,您可能会选择仅创建最能匹配常见类型的两个索引。