2014-11-03 59 views
1

我有以下的功能,我想在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 
      WHERE id = $1 and login = $2 
) 
    AND 
    NOT EXISTS (SELECT true 
      FROM test_no_read_access 
      WHERE id = $1 and login = $2 
) 
$BODY$ 

这,只要我有工作细到只有关注关于功能的正确性。由于查询分析器告诉我,必须对每行进行函数评估,因此EXISTS子句无法按预期进行优化。事实上,相比于以下查询查询是很慢(内联EXISTS子句而不SELECT子句):

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 
) 

功能has_access(ID,登录)的目的是将一些访问规则的函数,然后在不同的查询中使用它。我的意思是,这是可以做到这样的事情来获得良好的性能:

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$ 

但现在我只有在功能一个表一个子查询,这是不是在我的情况非常有用。有关如何正确执行此操作以避免遇到性能问题的任何建议?

谢谢!

+0

EXISTS趋向于导致相关子查询,这是数据库管理系统,以优化硬;使用IN/NOT IN往往更有效率。 – okaram 2014-11-04 00:39:10

+0

@okaram:完全错误。请注意,在这种情况下,没有相关的子查询,因为没有主查询。 – wildplasser 2014-11-04 00:52:19

+0

@wildplasser,该函数中的查询是不相关的,但上面的是(但我没有明白,当我发表评论时,问题是函数:) – okaram 2014-11-04 01:43:26

回答

0

好吧,我想我明白你的问题是什么;函数调用不可优化,所以您需要在函数外执行查询;像

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) 

检查http://sqlfiddle.com/#!12/94a02/2

+1

没有理由更喜欢'NOT IN(.. 。)'这里; “不存在(...)”工作得很好,或者甚至更好。 OQ中的性能问题在函数调用中,不能由优化器分解。 – wildplasser 2014-11-04 00:56:32

+0

@wildplasser我现在明白问题是函数调用;然而,通常在/不在查询中更容易优化,对吗? EXISTS倾向于做相关的子查询(需要引用查询中的外部行),这对优化器来说更难 – okaram 2014-11-04 01:41:53

+1

在过去的几年里,在我几乎所有在Postgres的大量测试中,'NOT EXISTS'结果都比'NOT IN'。另外,'NOT IN'在NULL值方面表现出棘手的行为。 [更多这里。](http://stackoverflow.com/a/19364694/939860)。即将到来的第9.4版可能会有变化。不是说有,也没有期待。只是没有测试,但。 – 2014-11-04 22:17:03

相关问题