-2

以下は、「従来の」方法で行われた単純化されたサンプル クエリです (サンプル クエリは PostgreSQL 8.3 でテストされています)。

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

問題は、同じバインド変数を 2 回渡すのが面倒なことです (より複雑なクエリで 6 回以上必要な場合はなおさらです)。

もちろん、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 よりもわずかに遅く実行されます (ただし、クエリの準備には、どちらの方法よりも時間がかかります)。他の 2 つのオプション)。

だから私の質問は:

バインド変数の繰り返しを避ける方法として、この種の JOIN/sub-select 構造は、より複雑なクエリの良いフォームまたは悪いフォームと見なされますか?

4

1 に答える 1

2

あなたの質問に対する直接の答えではありませんが、この特定のケースでは、次のようにクエリを書き直すことができるはずです。

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

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