4

http://www.postgresql.org/docs/9.2/static/hstore.html状态:

hstore has GiST and GIN index support for the @>, ?, ?& and ?| operators

然而,索引不适用于EXISTfunction,这似乎等同于?operator。

运算符和函数之间有什么区别使得索引一个或另一个变得更加困难?

Hstore 扩展的未来版本可能使这些真正等效吗?

4

2 回答 2

2

查找“CREATE OPERATOR CLASS”的文档,该文档描述了如何为任意运算符创建索引方法。您还需要先使用“CREATE OPERATOR”创建基于 EXIST 函数的运算符。

(警告:我没有使用 hstore 的经验)

http://www.postgresql.org/docs/9.0/static/sql-createoperator.html

http://www.postgresql.org/docs/9.0/static/sql-createopclass.html

于 2013-02-04T14:30:06.910 回答
1

这是你的问题:PostgreSQL 函数是不透明的。规划者无法知道运算符和函数在语义上是等价的。这经常出现。

PostgreSQL 确实具有函数索引,因此您可以索引不可变函数的输出,但这可能不会让事情在这里完美地工作,因为您可能只能索引哪些行对于给定的调用返回 true,但这仍然非常有用带有部分索引。例如,您总是可以执行以下操作:

CREATE INDEX bar_has_aaa ON foo(exists(bar, 'aaa'));

或者

CREATE INDEX bar_has_aaa ON foo(id) where exists (bar, 'aaa');

但我不认为这正是你需要它去的地方。希望它为您指明正确的方向。

编辑:以下让我觉得更好的解决方法。假设我们有一个表 foo:

 CREATE TABLE foo (
        id serial,
        bar hstore
 );

我们可以创建一个表方法 bar_keys:

CREATE FUNCTION bar_keys(foo) RETURNS text[] IMMUTABLE LANGUAGE SQL AS $$
    SELECT akeys($1.bar);
$$;

然后我们可以使用 GIN 对其进行索引:

 CREATE INDEX foo_bar_keys_idx ON foo USING gin(bar_keys(foo));

我们可以在查询中使用它:

  SELECT * FROM foo WHERE foo.bar_keys @> array['aaa'];

那应该使用索引。请注意,您可以直接索引/使用键,但我认为虚拟列会导致更清晰的语法。

于 2013-01-30T06:41:18.723 回答