SELECT COUNT (*) FROM users;
count
- 205043
SET enable_seqscan TO on; EXPLAIN ANALYZE SELECT COUNT(*) FROM users;
QUERY PLAN
- Aggregate (cost = 15813.70..15813.71 rows = 1 width = 0) (actual time = 82.907..82.908 rows = 1 loops = 1)
-> Seq Scan on users (cost = 0.00..15296.16 rows = 207016 width = 0) (actual time = 0.014..55.505 rows = 205043 loops = 1)
Planning time: 0.211 ms
Execution time: 82.967 ms
SET enable_seqscan TO off; EXPLAIN ANALYZE SELECT COUNT(*) FROM users;
QUERY PLAN
- Aggregate (cost = 20156.95..20156.96 rows = 1 width = 0) (actual time = 117.553..117.554 rows = 1 loops = 1)
-> Bitmap Heap Scan on users (cost = 4343.25..19639.41 rows = 207016 width = 0) (actual time = 28.354..92.228 rows = 205043 loops = 1)
Heap Blocks: exact = 13226
-> Bitmap Index Scan on users_pkey (cost = 0.00 ..4291.50 rows = 207016 width = 0) (actual time = 25.247..25.247 rows = 229621 loops = 1)
Planning time: 0.141 ms
Execution time: 117.724 ms
CREATE SEQUENCE users_count_seq MINVALUE 0 START 0;
CREATE OR REPLACE FUNCTION rows_count( tablename text, reset bool default false ) RETURNS bigint LANGUAGE plpgsql AS $$ DECLARE rows_count bigint; tablename_seq text; BEGIN tablename_seq := tablename || '_count_seq'; -- IF reset IS TRUE THEN EXECUTE 'SELECT setval($1,count(*)) FROM '||tablename USING tablename_seq INTO rows_count; -- ELSE EXECUTE 'SELECT last_value FROM '||tablename_seq INTO rows_count; END IF; RETURN rows_count; END; $$;
CREATE OR REPLACE FUNCTION rows_count_update_trigger() RETURNS TRIGGER LANGUAGE plpgsql AS $$ DECLARE tablename_seq text; BEGIN tablename_seq := TG_TABLE_NAME || '_count_seq'; -- INSERT IF TG_OP = 'INSERT' THEN EXECUTE 'SELECT nextval($1) FOR UPDATE' USING tablename_seq; RETURN NEW; -- DELETE ELSEIF TG_OP = 'DELETE' THEN EXECUTE 'SELECT setval($1,nextval($1)-2) FOR UPDATE' USING tablename_seq; RETURN OLD; -- TRUNCATE ELSEIF TG_OP = 'TRUNCATE' THEN EXECUTE 'SELECT setval($1,0) FOR UPDATE' USING tablename_seq; RETURN OLD; END IF; END; $$;
CREATE CONSTRAINT TRIGGER rows_count_update_trigger AFTER INSERT OR DELETE ON users INITIALLY DEFERRED FOR EACH ROW EXECUTE PROCEDURE rows_count_update_trigger(); CREATE TRIGGER rows_count_reset_trigger AFTER TRUNCATE ON users FOR EACH STATEMENT EXECUTE PROCEDURE rows_count_update_trigger();
SELECT rows_count ('users', true);
rows_count
- 205043
EXPLAIN ANALYZE SELECT rows_count('users');
QUERY PLAN
- Result (cost = 0.00..5.25 rows = 1000 width = 0) (actual time = 0.242..0.244 rows = 1 loops = 1)
Planning time: 0.033 ms
Execution time: 0.260 ms
Source: https://habr.com/ru/post/276055/
All Articles