-2

这是一个简化的示例查询,以“传统”方式完成(在 PostgreSQL 8.3 中测试的示例查询):

PREPARE a AS SELECT *
FROM users
WHERE uid=$1
    OR parent=$2;
EXECUTE a(0,0);

问题是,两次传递相同的绑定变量很麻烦(更复杂的查询需要六次或更多次)。

当然,SQL 允许在同一个查询中多次使用同一个绑定变量:

PREPARE b AS SELECT *
FROM users
WHERE uid=$1
    OR parent=$1;
EXECUTE b(0);

但是许多 DB API 层不支持(或者不容易),因此使用这种方法变得更加麻烦。

我可以通过针对子选择添加一个 JOIN 来解决这个问题:

PREPARE c AS SELECT uids.*
FROM users
JOIN (SELECT $1::INT AS uid) AS x ON true
WHERE uids.uid=x.uid 
    OR uids.parent=x.uid;
EXECUTE c(0);

Explain 表明,正如人们所期望的那样,后一个选项具有最复杂的执行计划,但是,至少在这个示例中,它始终比 a 执行得快,并且几乎不比 b 慢(尽管准备查询比任何一个都花费更长的时间)其他两个选项)。

所以我的问题是:

对于更复杂的查询,这种 JOIN/子选择结构是好是坏,作为避免重复绑定变量的一种方式?

4

1 回答 1

2

不是您问题的直接答案,但在这种特殊情况下,您应该能够像这样重写您的查询:

PREPARE b AS SELECT *
FROM users
WHERE $1 IN (uid, parent);

EXECUTE b(0);
于 2012-07-17T20:49:40.090 回答