PostgreSQLテーブルの行数を数える必要があります。この場合、条件が満たされる必要はありません。クエリ速度が大幅に向上した場合は、行の見積もりを取得することは完全に許容されます。
基本的に、select count(id) from <table>
正確な結果が得られないことを意味する場合でも、できるだけ速く実行したいと考えています。
PostgreSQLテーブルの行数を数える必要があります。この場合、条件が満たされる必要はありません。クエリ速度が大幅に向上した場合は、行の見積もりを取得することは完全に許容されます。
基本的に、select count(id) from <table>
正確な結果が得られないことを意味する場合でも、できるだけ速く実行したいと考えています。
非常に迅速な見積もりの場合:
SELECT reltuples FROM pg_class WHERE relname = 'my_table';
ただし、いくつかの注意点があります。1つは、relname
で必ずしも一意ではありませんpg_class
。relname
データベースの複数のスキーマに同じテーブルが複数存在する可能性があります。明確にするために:
SELECT reltuples::bigint FROM pg_class WHERE oid = 'my_schema.my_table'::regclass;
テーブル名をスキーマ修飾しない場合、キャストregclass
は現在を監視しsearch_path
て最適なものを選択します。また、テーブルがのどのスキーマにも存在しない(または表示されない)search_path
場合は、エラーメッセージが表示されます。マニュアルのオブジェクト識別子タイプを参照してください。
特に大きなカウントの場合、数値を適切にbigint
フォーマットするためのキャスト。real
また、reltuples
多かれ少なかれ時代遅れになる可能性があります。これをある程度補う方法があります。新しく改善されたオプションを使用して、この後の回答を参照してください。
また、クエリpg_stat_user_tables
は何倍も遅くなります(ただし、フルカウントよりもはるかに高速です)。これは、いくつかのテーブルのビューであるためです。
大きなテーブルの場合はカウントが遅いため、次の方法で詳細な見積もりを取得できます。
SELECT reltuples::bigint AS estimate
FROM pg_class
WHERE relname='tableName';
そして、その非常に高速な結果は変動しませんが、それでも厳密な見積もりです。
reltuples
はpg_class
テーブルの列であり、「テーブルの行数。これはプランナーが使用する推定値にすぎません。VACUUM、ANALYZE、およびCREATE INDEXなどのいくつかのDDLコマンドによって更新されます」(手動)pg_class
は、テーブルと、列があるか、テーブルに類似している他のほとんどすべてをカタログ化します。これには、インデックス(ただし、pg_indexも参照)、シーケンス、ビュー、複合型、およびいくつかの種類の特別な関係(手動)が含まれます。インデックス付きフィールド(できれば「id」)でCOUNT()を実行する以外に、次善の策は、INSERTのトリガーを使用して実際に行数をテーブルにキャッシュすることです。当然、代わりにキャッシュをチェックします。
概算として、これを試すことができます(https://wiki.postgresql.org/wiki/Count_estimateから):
select reltuples from pg_class where relname='tablename';
INSERTまたはDELETEの後にトリガーを使用するだけで、テーブル内のカウントの正確な値を要求できます。
CREATE TABLE tcounter(id serial primary key,table_schema text, table_name text, count serial);
insert into tcounter(table_schema, table_name,count) select 'my_schema', 'my_table', count(*) from my_schema.my_table;
トリガーを使用します
CREATE OR REPLACE FUNCTION ex_count()
RETURNS trigger AS
$BODY$
BEGIN
IF (TG_OP='INSERT') THEN
UPDATE tcounter set count = count + 1 where table_schema = TG_TABLE_SCHEMA::TEXT and table_name = TG_TABLE_NAME::TEXT;
ELSIF (TG_OP='DELETE') THEN
UPDATE tcounter set count = count - 1 where table_schema = TG_TABLE_SCHEMA::TEXT and table_name = TG_TABLE_NAME::TEXT;
END IF;
RETURN NEW;
END$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
CREATE TRIGGER tg_counter AFTER INSERT OR DELETE
ON my_schema.my_table FOR EACH ROW EXECUTE PROCEDURE ex_count();
そしてカウントを求める
select * from tcounter where table_schema = 'my_schema' and table_name = 'my_table'
これは、最初のレコードを初期化するためにcount(*)を1回選択することを意味します
システムテーブル「pg_stat_user_tables」から見積もりを取得できます。
select schemaname, relname, n_live_tup
from pg_stat_user_tables
where schemaname = 'your_schema_name'
and relname = 'your_table_name';
データベースが小さい場合は、@mike-sherrill-cat-recallのようなすべてのテーブルの見積もりを取得できます。ただし、このコマンドはすべてのテーブルを一覧表示します。
SELECT schemaname,relname,n_live_tup
FROM pg_stat_user_tables
ORDER BY n_live_tup DESC;
出力は次のようになります。
schemaname | relname | n_live_tup
------------+--------------------+------------
public | items | 21806
public | tags | 11213
public | sessions | 3269
public | users | 266
public | shops | 259
public | quantities | 34
public | schema_migrations | 30
public | locations | 8
(8 rows)