@AE42

Как оптимизировать счетчик PG?

У меня есть небольшая статистика в моём приложение
Кол-во зарегистрированных пользователей и кол-во пользователей, которые находятся онлайн и т.д

Кол-во записей в таблице составляет более 5 миллионов, при этом очень часто происходит INSERT

Методы которые, я уже пробовал:
COUNT
SELECT COUNT(*) FROM users
Данный способ не подходит, так как выборка занимает около 1 секунды

Был опыт с треггерами, но, к сожалению, пришлось от него отказаться из-за того, что обычный INSERT выполнялся достаточно долго (от 2-5 секунд)
drop table if exists user_aggregate;
drop trigger if exists user_aggregate_trigger on user_info;
drop function if exists user_aggregate();

create table user_aggregate (
    id int not null primary key,
    user_aggregate int not null
);

create or replace function user_aggregate()
returns trigger
as $$
begin
    insert into user_aggregate (id, user_aggregate)
    values (1, (select count(id) from user_info))
    on conflict (id) do
    update set user_aggregate = excluded.user_aggregate;
    return new;
end
$$ language plpgsql;

create trigger user_aggregate_trigger
after insert or delete on user_info
for each row execute procedure user_aggregate();

insert into user_aggregate (id, user_aggregate)
values (1, (select count(id) from user_info))
on conflict (id) do
update set user_aggregate = excluded.user_aggregate;


MAX
SELECT MAX(id) FROM users
Вариант хороший, но хотелось бы учитывать реальное кол-во записей
  • Вопрос задан
  • 108 просмотров
Решения вопроса 1
@bacon
Отдельная таблица с ключами (кол-во зарегистрированных пользователей и кол-во пользователей, которые находятся онлайн и т.д) и значениями. Зашел юзер, update set value = value + 1 where key='online_user', вышел value = value - 1, только не на уровне триггеров, а на уровне приложения. Со временем появляются искажения значений, из-за различных ошибок и неучтенных состояний, поэтому раз в какой-то период (час, сутки) ключи вычисляется в фоне через SELECT COUNT(*) FROM users и т.п. Так же подобное можно держать не в postgresql, а в redis, memcache или т.п.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы