PostgresのJOIN条件とWHERE条件


12

Postgres初心者はこちら。

このクエリが最適化されているかどうか疑問に思っていますか?100%必要な値だけを結合し、すべての動的条件をWHERE句に残そうとしました。下記参照。

SELECT *
    FROM
      myapp_employees
    JOIN myapp_users ON
      myapp_users.user_id=myapp_employees.user_id
    JOIN myapp_contacts_assoc ON
      myapp_contacts_assoc.user_id=myapp_users.user_id
    JOIN myapp_contacts ON
      myapp_contacts.contact_id=myapp_contacts_assoc.contact_id
    WHERE
      myapp_contacts.value='test@gmail.com' AND
      myapp_contacts.type=(1)::INT2 AND
      myapp_contacts.is_primary=(1)::INT2 AND
      myapp_contacts.expired_at IS NULL AND
      myapp_employees.status=(1)::INT2 AND
      myapp_users.status=(1)::INT2
    LIMIT 1;

注:コンテキストについては、このプロシージャはユーザーが従業員でもあるかどうかを確認しています(昇格された特権/別のユーザータイプ)。

とにかく、これは正しい方法ですか?たとえば、JOIN ONには、expired_at IS NULLのチェックなど、より多くのステートメントを含める必要がありますか?なぜ、またはなぜこれが意味をなさないのですか?


Postgresのバージョンはどうですか?(SELECT version();
Erwin Brandstetter 2016年

@ErwinBrandstetter PostgreSQL 9.3.14を実行しています。これは各機能で必要なものですか?
Dan、

2
いいえ、dba.SEでは、多くの質問に影響を与えるため、関連するソフトウェアバージョンを宣言する必要があります。
Erwin Brandstetter 2016年

回答:


14

論理的に、それはの句に参加して、あなたが条件を置くかどうかまったく違い行いませんINNER JOINまたはWHERE同じの句をSELECT。効果は同じです。

(そうではありませんOUTER JOIN!)

デフォルト設定で動作している間も、クエリプランやパフォーマンスに違いはありません。Postgresは、テーブルの数が(デフォルト)を超えない限り、結合とJOINWHERE条件を自由に並べ替えて、最適なクエリプランを探すことができjoin_collapse_limitます8。詳細:

可読性と保守性は、それぞれの中に、接続テーブルその場所の条件に理にかなっているJOIN句との一般的な条件WHERE句。

クエリは問題なく見えます。ただし、テーブルエイリアスを使用してノイズを削減します。

細部:

int2 '1'または1::int2よりも賢明です(1)::INT2。そして、明確に定義された数値データ型の値と比較しながら、単純な数値定数1でも十分です。


2

いくつかのポイント

  1. 同じ名前(user_id)で条件に参加している場合は、USING (user_id)ではなくを使用できますON (a.user_id = b.user_id)。これにより、冗長列が出力される可能性も回避されます(SELECT *本番環境で実行している場合)。

  2. 1::int2問題があります。どちらかstatus、そしてis_primary、その他は、すでにさint2れた場合にはリテラル1を自動的にINT2にキャストされる、またはPGはフィットを見ているようINT2はint型にキャスト。または、それらを通常のintとして格納し、それが計算に違いをもたらすかのようにそれらをキャストダウンする場合-それはそうではありません-キャストだけでは、その命題が失われます。

  3. 可能であれば、すべての:: int2はおそらくとして保存する必要がありますboolean。次に、WHERE条件をより単純にすることもできます。

  4. タイプとステータスについては、タイプが必要な場合がありますENUM

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.