0

私はPostgreSQLで実行しているSQLクエリを持っています.これは次の行に沿っています:

SELECT DISTINCT items.id,
   CASE WHEN items.marker is not null
          THEN (items.rating - (educations.cards_done - items.marker))
        WHEN items.marker is null
          THEN 0 
   END AS order
FROM items
INNER JOIN educations ON educations.item_id = items.id 
WHERE items.active = true
ORDER BY 
   CASE WHEN items.marker is not null
          THEN (items.rating - (educations.cards_done - items.marker))
        WHEN items.marker is null
          THEN 0 
   END
LIMIT 10

PostgreSQL の case ステートメントを使用して、その順序でインデックスを作成することは可能ですか? そうでない場合、このクエリを高速化する他の方法はありますか? ご協力いただきありがとうございます。

4

1 に答える 1

1

CASE ステートメント自体を最適化することから始めることができます。2番目WHENは冗長です。NULL2 つのケース (および)しか存在できませんNOT NULL。簡素化する:

CASE WHEN items.marker is not null 
     THEN ((items.rating + items.marker) - educations.cards_done)
ELSE 0 END

索引付けに関する限り、索引で複数の表の値を使用する方法を知りません。そのためには、トリガーによって更新されるテーブルの 1 つでマテリアライズド ビューまたは冗長列を使用する必要があります。ORDERパフォーマンスが非常に重要であり、関連するテーブルがほとんど読み取られ、めったに書き込まれない場合にのみ、私はそのようなことについて考えます。

educations.item_idAND に既にインデックスがあると思いますitems.idか?(主キーは自動インデックスで、外部キーはそうではありません。)

active = true部分インデックスがオンになっているアイテムの割合によっては、items役立つ場合があります。それが機能するには、アクティブなアイテムが少数派である必要があります。

CREATE INDEX foo_idx ON items(id) WHERE active;

EXPLAIN ANALYZEクエリでインデックスが使用されるかどうかをテストします。関連するテーブルの大部分を選択すると、シーケンシャル スキャンが高速になり、インデックスが使用されなくなります。

于 2011-11-23T18:59:53.670 に答える