sql >> データベース >  >> RDS >> PostgreSQL

Postgres LEFT JOIN with SUM、欠落しているレコード

    通常、すべてまたはほとんどの行をフェッチする場合に最速になります :

    SELECT pp.id
         , COALESCE(pt.a_dog_ct, 0) AS alive_dogs_count
         , COALESCE(pt.a_cat_ct, 0) AS alive_cats_count
    FROM   people pp
    LEFT   JOIN (
       SELECT person_id
            , count(kind = 'dog' OR NULL) AS a_dog_ct
            , count(kind = 'cat' OR NULL) AS a_cat_ct
       FROM   pets
       WHERE  alive
       GROUP  BY 1
       ) pt ON pt.person_id = pp.id;
    

    ここではインデックスは関係ありません。全表スキャンが最速になります。 除く 生きているペットがまれの場合 場合は、部分インデックス 役立つはずです。いいね:

    CREATE INDEX pets_alive_idx ON pets (person_id, kind) WHERE alive;
    

    クエリ(person_id, kind)に必要なすべての列を含めました インデックスのみのスキャンを許可します。

    SQLフィドル。

    通常、小さなサブセットまたは単一の行で最速です。 :

    SELECT pp.id
         , count(kind = 'dog' OR NULL) AS alive_dogs_count
         , count(kind = 'cat' OR NULL) AS alive_cats_count
    FROM   people pp
    LEFT   JOIN pets pt ON pt.person_id = pp.id
                       AND pt.alive
    WHERE  <some condition to retrieve a small subset>
    GROUP  BY 1;
    

    少なくともpets.person_idにインデックスが必要です このため(または上からの部分インデックス)-そしておそらくそれ以上、WHERE 状態。

    関連する回答:



    1. 操作'='の照合(utf8mb4_unicode_ci、IMPLICIT)と(utf8mb4_general_ci、IMPLICIT)の不正な組み合わせ

    2. C#の単一のOracleコマンドで複数のクエリを実行する

    3. MySQL、PostgreSQL、Redis™のScaleGridDigitalOceanサポートが利用可能になりました

    4. リレーショナルデータベースで大きな文字列フィールドの編集履歴を保持する方法