2015-08-24 4 views
1

У меня есть следующие таблицы tbl:Как принудительно использовать GroupAggregates?

id user_id  amount 
PK integer  integer 

Я также создал индекс по user_id в

CREATE INDEX idx_fk_user_id 
    ON tbl 
    USING btree 
    (user_id); 

Теперь объяснить план выполнения

EXPLAIN ANALYZE SELECT SUM(amount) s 
FROM tbl 
GROUP BY user_id 

который вернул мне

"HashAggregate (cost=117903.97..117905.14 rows=118 width=9) (actual time=1869.591..1869.623 rows=207 loops=1)" 
" -> Seq Scan on tbl (cost=0.00..101439.31 rows=3292931 width=9) (actual time=0.017..501.316 rows=3292931 loops=1)" 

Насколько я понимаю, HashAggregates использует большой объем памяти. Таким образом, я полагаю, что вместо этого было бы полезно использовать GroupAggregates. Таблица используется в основном для чтения (все данные записываются заданием планировщика один раз в день).

Как подать заявку GroupAggregates здесь, а не HashAggregates?

+0

Вопрос заключается в том, почему вы хотите, чтобы «применить» 'GroupAggregate"? Если планировщик решил использовать 'HashAggregate' то, видимо, имеется достаточно памяти и потому что он считает, что это самая эффективная вещь. Объем памяти, который можно использовать для такой операции, определяется настройкой «work_mem». Если вы уменьшите это, вы можете увидеть «GroupAggregate», но я сомневаюсь, что ваш запрос будет быстрее. –

ответ

1

Вы понимаете, что настройки changing требуют разных значений на разных машинах для разных таблиц, правильно? Так что я играл с моим столом и здесь мои эффективных значения:

set seq_page_cost = 8; 
set enable_hashagg to false; 

Первых силами использования индекса (мой стол маленький и процессор слаб, и SSD быстро), делая IO сканирования более дорогое.

Вторая делает то, что вы хотели.

Таким образом, после установки SESSION valiable У меня есть план:

GroupAggregate (cost=11.66..12.68 rows=45 width=8) (actual time=0.152..0.309 rows=45 loops=1) 
    -> Sort (cost=11.66..11.85 rows=76 width=8) (actual time=0.139..0.155 rows=76 loops=1) 
     Sort Key: index_i 
     Sort Method: quicksort Memory: 28kB 
     -> Index Only Scan using index_i on table_t (cost=0.14..9.28 rows=76 width=8) (actual time=0.021..0.055 rows=76 loops=1) 
       Heap Fetches: 0 
Total runtime: 0.380 ms 

Update: в вашем link есть Консультировать

Для PostgreSQL, необходимо добавить заказ пунктом, чтобы сделать индекс с NULLS LAST сортировка, пригодная для конвейерной группы.

Это не помогло в одиночку ...

Смежные вопросы