PostgreSQLでテーブルの行数を速く取得する方法
まず、
create table test (id serial primary key, data text);
でテーブルを作成する。
そして、データをインポートする。
カウント関数を呼び出す
lenovo=# select count(*) from test;
count
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
4194304
(1 row)
Time: 1040.870 ms遅いじゃないか
ネットで調べて、いろんな方法がありますが、triggerを使うとか。
面倒くさいと思います。
ほかの方法、pg_classを利用する。試してみると、
lenovo=# select reltuples::integer from pg_class where relname='test';
reltuples
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
4194304
(1 row)
Time: 14.990 ms正確じゃん。
でも…
lenovo=# insert into test (data) values ('b');
INSERT 0 1
Time: 6.013 ms
lenovo=# select reltuples::integer from pg_class where relname='test';
reltuples
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
4194304
(1 row)
Time: 0.954 ms
lenovo=#ダメなんだか…
この方法を使う前にvacuumは必要だと聞いた。
そして、私はpgAdminを使うときの何かを思い出した。
スキーマ→public→テーブル→test
右の統計情報に、有効タプルがあります。
pg_classのデータと違って、それは正確だな…
やつはどこにこの情報を取得できるのかな
私はPostgreSQLのステートメントログをオンに設定して、pg_stat_user_tablesから取得できると知りました
lenovo=# select n_live_tup from pg_stat_user_tables where relname='test' and sch
emaname='public';
n_live_tup
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
4194305
(1 row)
Time: 16.763 ms
lenovo=#これ、はやい。それに、正確だ。
lenovo=# insert into test (data) values ('b');
INSERT 0 1
Time: 1.272 ms
lenovo=# select n_live_tup from pg_stat_user_tables where relname='test' and schemaname='public';
n_live_tup
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
4194306
(1 row)
Time: 14.855 ms
lenovo=#前に言った問題もない。
なお、ほかの問題があるけど
日本語が下手ので説明はちょっと難しいに感じる
これは結果:
lenovo=# begin transaction;
BEGIN
Time: 0.669 ms
lenovo=# select n_live_tup from pg_stat_user_tables where relname='test' and schemaname='public';
n_live_tup
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
4194306
(1 row)
Time: 16.083 ms
lenovo=# insert into test (data) values ('b');
INSERT 0 1
Time: 0.580 ms
lenovo=# select n_live_tup from pg_stat_user_tables where relname='test' and schemaname='public';
n_live_tup
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
4194306
(1 row)
Time: 2.081 ms
lenovo=# select count(*) from test;
count
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
4194307
(1 row)
Time: 1062.131 ms
lenovo=# rollback;
ROLLBACK
Time: 44.899 ms
lenovo=# select n_live_tup from pg_stat_user_tables where relname='test' and schemaname='public';
n_live_tup
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
4194306
(1 row)
Time: 15.594 ms
lenovo=# select count(*) from test;
count
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
4194306
(1 row)
Time: 1059.174 ms
lenovo=#
なお何か問題があれば、気軽にツイッターで@sorayukinoyumeへどうぞ。
では。
雷鳴