这是一个简化的示例查询,以“传统”方式完成(在 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/子选择结构是好是坏,作为避免重复绑定变量的一种方式?