「AORexists(B)」クエリでのPostgresの最適化

delCano

Postgresの最適化の特定のケースで多くの問題が発生しています。

基本的に、次のように簡略化する3つのテーブルがあります。

  • Place:id、name(String)、select(Boolean)
  • Bookmark:id、user(整数)、place(整数)
  • User:id、name(文字列)

Placeテーブルには、数百万行(と成長)を持っているが、それらの比較的少量を持っているselect本当のよう。

私はこれらのテーブルにいくつかのインデックスを持っていますが、明らかにすべてidに加えて、部分的なインデックスplace where "select"=truebookmark(ユーザー、場所)コンボに一意のインデックスがあります他にもありますが、ここでは関係ないと思います。

次のタイプのクエリを実行すると、次のようになります。

SELECT * 
FROM place 
WHERE "select" 
LIMIT 10;

3msかかります。

次のタイプのクエリを実行すると、次のようになります。

SELECT * 
FROM place 
WHERE exists (SELECT id 
              FROM bookmark 
              WHERE user IN (1,2,3,4) 
                AND bookmark.place = place.id) 
LIMIT 10;

それはまた速く燃えています。

ただし、次のようにOR両方の条件でを実行すると、次のようになります。

SELECT * 
FROM place 
WHERE "select" 
   OR exists (SELECT id 
              FROM bookmark 
              WHERE user IN (1,2,3,4) 
                AND bookmark.place = place.id) 
LIMIT 10;

1秒以上に減速します。

コードで2つのクエリを実行して結果を組み合わせる以外に、これを最適化する方法はありますか?

ローレンツアルベ

古い問題ORは、パフォーマンスキラーです。

使用UNION

(SELECT * FROM place
 WHERE select
 LIMIT 10)
UNION
(SELECT * FROM place
 WHERE exists (SELECT 1 FROM bookmark
               WHERE user IN (1,2,3,4)
                 AND bookmark.place = place.id)
 LIMIT 10)
LIMIT 10;

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事