http://www.postgresql.org/docs/9.2/static/hstore.html状态:
hstore has GiST and GIN index support for the @>, ?, ?& and ?| operators
然而,索引不适用于EXIST
function,这似乎等同于?
operator。
运算符和函数之间有什么区别使得索引一个或另一个变得更加困难?
Hstore 扩展的未来版本可能使这些真正等效吗?
http://www.postgresql.org/docs/9.2/static/hstore.html状态:
hstore has GiST and GIN index support for the @>, ?, ?& and ?| operators
然而,索引不适用于EXIST
function,这似乎等同于?
operator。
运算符和函数之间有什么区别使得索引一个或另一个变得更加困难?
Hstore 扩展的未来版本可能使这些真正等效吗?
查找“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
这是你的问题: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'];
那应该使用索引。请注意,您可以直接索引/使用键,但我认为虚拟列会导致更清晰的语法。