部分索引用途之一:从索引中排除那些查询不感兴趣的值。这导致了上述相同的好处,但它防止了通过索引来访问“不感兴趣的”值,即便在这种情况下一个索引扫描是有益的。显然,为这种场景建立部分索引需要很多考虑和实验。
如果我们有一个表包含已上账和未上账的订单,其中未上账的订单在整个表中占据一小部分且它们是最经常被访问的行。我们可以通过只在未上账的行上创建一个索引来提高性能。创建索引的命令如下:
CREATE INDEX orders_unbilled_index ON orders (order_nr)
WHERE billed is not true;
使用该索引的一个可能查询是:
SELECT * FROM orders WHERE billed is not true AND order_nr < 10000;
然而,索引也可以用于完全不涉及order_nr的查询,例如:
SELECT * FROM orders WHERE billed is not true AND amount > 5000.00;
这并不如在amount列上部分索引有效,因为系统必须扫描整个索引。然而,如果有相对较少的未上账订单,使用这个部分索引来查找未上账订单将会更好。
注意这个查询将不会使用该索引:
SELECT * FROM orders WHERE order_nr = 3501;
订单3501可能在已上账订单或未上账订单中。
本例也显示索引列和谓词中使用的列并不需要匹配。GBase 8c支持使用任意谓词的部分索引,只要其中涉及的只有被索引表的列。然而,记住谓词必须匹配在将要受益于索引的查询中使用的条件。更准确地,只有当系统能识别查询的WHERE条件从数学上索引的谓词时,一个部分索引才能被用于一个查询。GBase 8c并不能给出一个精致的定理证明器来识别写成不同形式在数学上等价的表达式(一方面创建这种证明器极端困难,另一方面即便能创建出来对于实用也过慢)。系统可以识别简单的不等蕴含,例如“x < 1”蕴含“x < 2”;否则谓词条件必须准确匹配查询的WHERE条件中的部分,或者索引将不会被识别为可用。匹配发生在查询规划期间而不是运行期间。因此,参数化查询子句无法配合一个部分索引工作。例如,对于参数的所有可能值来说,一个具有参数“x < ?”的预备查询绝不会蕴含“x < 2”。