# 11.5.组合多个索引

单个索引扫描只能使用查询子句,这些子句将索引的列与其运算符类的运算符一起使用,并与.例如,给定(a,b)一个查询条件,如其中a=5,b=6可以使用索引,但是像这样的查询其中a=5或b=6无法直接使用索引。

幸运的是,PostgreSQL能够组合多个索引(包括同一索引的多次使用),以处理单索引扫描无法实现的情况。系统可以形成多个索引扫描的条件。例如,像其中x=42或x=47或x=53或x=99可以分解为四个单独的索引扫描十、,每次扫描使用一个查询子句。然后将这些扫描的结果相加以生成结果。另一个例子是,如果我们在十、y,一种可能的查询实现,如其中x=5,y=6就是将每个索引与适当的查询子句一起使用,然后将索引结果放在一起,以标识结果行。

为了组合多个索引,系统会扫描每个需要的索引,并准备一个位图在内存中,给出与该索引条件匹配的表行的位置。然后,根据查询的需要,将位图进行and和OR运算。最后,访问并返回实际的表行。表行是按物理顺序访问的,因为位图就是这样布置的;这意味着原始索引的任何排序都将丢失,因此如果查询具有订购人条款出于这个原因,而且因为每次额外的索引扫描都会增加额外的时间,所以规划人员有时会选择使用简单的索引扫描,即使还有其他可以使用的索引。

在除最简单的应用程序外的所有应用程序中,都有各种索引组合可能很有用,数据库开发人员必须做出权衡,以决定提供哪些索引。有时多列索引是最好的,但有时最好创建单独的索引并依赖索引组合功能。例如,如果您的工作负载包含有时只涉及列的混合查询十、,有时仅列y,有时两列,您可以选择在上创建两个单独的索引十、y,依靠索引组合来处理使用这两列的查询。您还可以在上创建多列索引(x,y)。对于涉及两个列的查询,此索引通常比索引组合更有效,但如中所述第11.3节,对于只涉及y,所以它不应该是唯一的索引。多列索引和独立索引的组合y服务相当好。仅适用于涉及十、,可以使用多列索引,但它会比十、单独地最后一种选择是创建所有三个索引,但这可能只有在搜索表的频率比更新表的频率高得多,并且所有三种类型的查询都很常见的情况下才是合理的。如果其中一种查询类型远不如其他类型常见,那么您可能会满足于只创建两个最匹配常见类型的索引。