Добрый день!
В интернете множество хвалебных отзывов о постгресе, у всех все хорошо и здорово, таблицы с миллиардами данных и пр.
В действительности же мы на данный момент имеем таблицу на 1.5 миллиона записей статистики, обычный запрос на count(*) выполняется 0.700 мс.
[SQL] EXPLAIN ANALYSE select count(*) from table
Aggregate (cost=174099.68..174099.69 rows=1 width=8) (actual time=787.417..787.418 rows=1 loops=1)
-> Seq Scan on table (cost=0.00..170511.54 rows=1435254 width=0) (actual time=0.444..637.771 rows=1435107 loops=1)
Planning time: 0.110 ms
Execution time: 787.479 ms
[SQL] EXPLAIN ANALYSE select count(*) from table where user_id=114
Aggregate (cost=166624.17..166624.18 rows=1 width=8) (actual time=482.791..482.792 rows=1 loops=1)
-> Bitmap Heap Scan on table (cost=2919.96..166234.64 rows=155811 width=0) (actual time=46.828..463.465 rows=156944 loops=1)
Recheck Cond: (user_id = 114)
Rows Removed by Index Recheck: 153189
Heap Blocks: exact=39222 lossy=26507
-> Bitmap Index Scan on idx_user_id (cost=0.00..2881.01 rows=155811 width=0) (actual time=36.766..36.766 rows=156944 loops=1)
Index Cond: (user_id = 114)
Planning time: 0.242 ms
Execution time: 483.520 ms
И это ведь простой подсчет кол-ва, а ведь требуется еще и агрегация отдельных столбцов, и джоины, и дистинкты, и еще много много чего.
Что мы упускаем? Нам просто нужно уметь быстро отфильтровать большой объем данных по заданной дате и пользователю. Партиционирование только усугубляет ситуацию, вероятно слишком малый объем данных.
UPD. Самый простой пример. Если миллион записей формата UUID, user_id, date. 95% запросов на select - это фильтр по user_id + date between(start, end). Что поможет в этом случае? Сейчас стоит btree-индекс на dt + user_id.
Заранее спасибо.