問題タブ [postgresql-10]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
postgresql - 大きなテーブルで未読ニュースを数える
私はかなり一般的な (少なくとも私が思うに) データベース構造を得ました: ニュース ( News(id, source_id)
) があり、各ニュースにはソース ( Source(id, url)
) があります。ソースは、Topic(id, title)
経由でトピック ( )に集約されますTopicSource(source_id, topic_id)
。さらに、User(id, name)
経由でニュースを既読としてマークできるユーザー ( ) がいますNewsRead(news_id, user_id)
。物事を明確にするための図を次に示します。
特定のユーザーのトピックの未読ニュースをカウントしたい。問題はNews
、テーブルが大きいことです (10^6 - 10^7 行)。幸いなことに、正確なカウントを知る必要はありません。このしきい値をカウント値として返すしきい値の後でカウントを停止してもかまいません。
1 つのトピックに対するこの回答に続いて、次のクエリを思いつきました。
(クエリ プラン 1 )。このクエリは、テスト データベースで約 50 ミリ秒かかりますが、これは許容範囲です。
ここで、複数のトピックの未読数を選択したいと考えています。私はそのように選択しようとしました:
(クエリ プラン 2 )。しかし、理由は不明ですが、テストデータでは約 1.5 秒かかりますが、個々のクエリの合計は約 0.2 ~ 0.3 秒かかります。
ここで明らかに何かが欠けています。2番目のクエリに間違いはありますか? 未読のニュースの数を選択するより良い (より速い) 方法はありますか?
追加情報:
- これは、DB構造とクエリのフィドルです。
- 私はSQLAlchemyでPostgresSQL 10を使用しています(ただし、生のSQLは今のところ問題ありません)。
テーブルサイズ:
UPD:クエリプランは、2番目のクエリを台無しにしたことを明確に示しています。どんな手がかりも大歓迎です。
UPD2:このクエリを横結合で試しました。これは、それぞれに対して最初の (最速の) クエリを実行するだけのはずですtopic_id
:
(クエリ プラン 3 )。しかし、Pg プランナーはこれについて異なる意見を持っているようです。インデックス スキャンとマージ結合の代わりに、非常に遅い seq スキャンとハッシュ結合を実行します。
sql - 複数列のユニーク制約で関数を使用する
私はこのテーブルを持っています:
テーブルを作成しようとすると、エラーが発生しsyntax error at or near "("
ます。2つの列を一意にするときに関数は好きLEAST
で許可されていませんか? GREATEST
最小関数と最大関数の目的は、1 つの ID が赤色の場合、青色の列の別のレコードにも含まれないようにすることです。