Function 函数中EXISTS子句的性能不佳
我想在sql查询Postgres 9.3中使用以下函数:Function 函数中EXISTS子句的性能不佳,function,postgresql,plpgsql,inline-code,Function,Postgresql,Plpgsql,Inline Code,我想在sql查询Postgres 9.3中使用以下函数: SELECT * FROM test_table tt WHERE has_access(tt.id, tt.login) CREATE OR REPLACE FUNCTION has_access(integer, integer) RETURNS boolean AS $BODY$ SELECT EXISTS (SELECT true FROM test_read_access WHE
SELECT * FROM test_table tt WHERE has_access(tt.id, tt.login)
CREATE OR REPLACE FUNCTION has_access(integer, integer)
RETURNS boolean AS
$BODY$
SELECT
EXISTS (SELECT true
FROM test_read_access
WHERE id = $1 and login = $2
)
AND
NOT EXISTS (SELECT true
FROM test_no_read_access
WHERE id = $1 and login = $2
)
$BODY$
只要我只关心函数的正确性,这就行了。因为查询分析器告诉我,必须为每一行计算函数,因此不能按预期优化EXISTS子句。实际上,与以下不包含SELECT子句而内联EXISTS子句的查询相比,查询速度非常慢:
SELECT * FROM test_table tt WHERE
EXISTS (SELECT true
FROM test_read_access
WHERE id = tt.id and login = tt.login
)
AND
NOT EXISTS (SELECT true
FROM test_no_read_access
WHERE id = tt.id and login = tt.login
)
该函数的目的是拥有_accessid,login是将函数中的一些访问规则分组,然后在不同的查询中使用它。我的意思是,这样做可以获得良好的性能:
SELECT * FROM test_table tt WHERE EXISTS (select has_access(tt.id, tt.login))
CREATE OR REPLACE FUNCTION has_access(integer, integer)
RETURNS SETOF boolean AS
$BODY$
SELECT true
FROM test_read_access
WHERE id = $1 and login = $2
$BODY$
但是现在我在函数中的一个表上只有一个子查询,这在我的例子中没有用处。有没有关于如何正确执行此操作以避免出现性能问题的建议
谢谢 好吧,我想我明白你的问题所在了;函数调用不可优化,因此需要在函数外部执行查询;差不多
SELECT *
FROM test_table
WHERE (id,login) IN (SELECT id,login FROM test_read_access)
AND (id,login) NOT IN (SELECT id,login FROM test_no_read_access)
CheckEXISTS倾向于导致相关子查询,这对于DBMS来说更难优化;在中/不在中使用往往更有效。@okaram:完全错误。请注意,在这种情况下,没有相关的子查询,因为没有主查询。@wildplasser,函数中的查询没有相关,但上面的查询是,但我不知道问题出在我发表评论时的函数上:没有理由不选择在。。。在这里不存在。。。同样有效,甚至更好。OQ中的性能问题在于函数调用,这是Optimizer无法解决的。@wildplasser我现在明白问题在于函数调用;但是,通常in/notin查询更容易优化,对吗?EXISTS倾向于做相关子查询需要引用查询内的外行,这对优化器来说比较困难。在过去几年中,我在Postgres中进行了大量的测试,结果表明,NOT EXISTS比NOT in更快。此外,NOT In在使用空值时表现出棘手的行为。即将到来的第9.4页可能会有变化。不说有,也不期待。只是还没有测试。