组合多个索引

PostgreSQL 9.4.4 中文手册
上一页 | 上一级 | 章 11. 索引 | 下一页

# 11.5. 组合多个索引

一个单独的索引扫描只能用于这样的条件子句：使用被索引字段和索引操作符类中的操作符， 并且这些条件以`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`上的索引更慢。最后一个选择是创建三个索引， 但是这种方法只有在表的更新远比查询少，并且所有三种查询都很普遍的情况下才是合理的。 如果其中一种查询比其它的少很多，那么你可能更愿意仅仅创建两种匹配更常见查询的索引。

上一页 | 起始页 | 下一页
索引和`ORDER BY` | 上一级 | 唯一索引