PostgreSQL:COUNT(*)はインデックスではなくシーケンシャルスキャンを使用します


12

COUNT(*)非常に小さくインデックスが付けられた主キーがあるのに、PostgreSQLがクエリのためにテーブルを順番にスキャンするのはなぜですか?

回答:


15

公式のwikiページはそれに答えを与えます:

[...]これが遅い理由は、PostgreSQLのMVCC実装に関連しています。複数のトランザクションがデータの異なる状態を見ることができるという事実は、「COUNT(*)」がテーブル全体のデータを要約する簡単な方法がないことを意味します。PostgreSQLは、ある意味ですべての行を調べなければなりません。これにより、通常、テーブル内のすべての行に関する情報を読み取る順次スキャンが行われます。[...]

さらに、ANALYZEを試行して、クエリプランナーの情報を再構築できます。

を使用してパフォーマンスを向上させる必要がありますCOUNT(an uniquly indexed field)が、これが非常に大きい場合は、seqスキャンが唯一の方法です。

非常に速い数字が必要で、スキーマを照会することを恐れていない場合は、次のことができます

SELECT reltuples FROM pg_class WHERE oid = 'your_table'::regclass

ただし、この値はテーブル内の「推定」(多くの場合正確ですが)タプル数であるため、この値に依存しないでください。


これは正しいとは思わない。COUNT(pk)パフォーマンスを改善する場所は何も読んでいません。常にseq-scanを実行すると思う
-vol7ron

1
正しいWHERE句がないと、seqスキャンが実行されます。postgresqlはインデックスを使用できる十分なselect句を使用しますが、テーブルに戻り、レポートしているタプルの可視性を確認します。
スコットマーロウ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.