为什么Postgres Hstore索引适合? (操作员)而不是EXIST(功能)?

时间:2013-01-22 21:41:55

标签: postgresql indexing hstore

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

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

但索引don't work for the EXIST function似乎等同于?运算符。

运算符和函数之间的区别是什么使得索引一个或另一个更难?

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

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:1)

这是你的问题:PostgreSQL函数是planner-opaque。规划者无法知道操作符和函数在语义上是等价的。这出现了很多。

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'];

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