Действительно медленная производительность в postgres - PullRequest
1 голос
/ 13 марта 2012

У меня есть таблица, в которую я вставляю только строки, а не удаляю. В каждом цикле я вставляю около 36 тыс. Строк.

Мне нужно получить строки из этой таблицы для выполнения операций. Проблема в каждом цикле, производительность запроса действительно очень плохая.

Например, в цикле 31:

explain analyze select exp(least(709,a.value)), a.from, a.to,a.material,a.transport from resultTable a where a.loop=31;
                                                                           QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
 Bitmap Heap Scan on resultTable a  (cost=36.58..4431.79 rows=2425 width=48) (actual time=7.351..33894.217 rows=34640 loops=1)
   Recheck Cond: (loop = 31)
   ->  Bitmap Index Scan on "resultTable_idx_mo"  (cost=0.00..35.97 rows=2425 width=0) (actual time=4.880..4.880 rows=34640 loops=1)
         Index Cond: (loop = 31)
 Total runtime: 33897.070 ms
(5 rows)

Для цикла 43:

explain analyze select exp(least(709,a.value)), a.from, a.to,a.material,a.transport from resultTable a where a.loop=43;
                                                                           QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
 Bitmap Heap Scan on resultTable a  (cost=36.58..4431.79 rows=2425 width=48) (actual time=10.129..125460.445 rows=34640 loops=1)
   Recheck Cond: (loop = 43)
   ->  Bitmap Index Scan on "resultTable_idx_mo"  (cost=0.00..35.97 rows=2425 width=0) (actual time=4.618..4.618 rows=34640 loops=1)
         Index Cond: (loop 43)
 Total runtime: 125463.516 ms
(5 rows)

Время растет как экспоненциальное. Я делаю VACUUM и REINDEX в каждом цикле (я пробовал и без, но результаты такие же).

Есть идеи, как улучшить время?

Заранее спасибо.

После раздела:

    QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 Result  (cost=14.47..2686.29 rows=1649 width=48) (actual time=18.562..220124.597 rows=34640 loops=1)
   ->  Append  (cost=14.47..2682.17 rows=1649 width=48) (actual time=5.189..32.743 rows=34640 loops=1)
         ->  Bitmap Heap Scan on resultTable a  (cost=14.47..1655.44 rows=866 width=48) (actual time=0.008..0.008 rows=0 loops=1)
               Recheck Cond: (loop = 60)
               ->  Bitmap Index Scan on "resultTable_idx_mo"  (cost=0.00..14.26 rows=866 width=0) (actual time=0.006..0.006 rows=0 loops=1)
                     Index Cond: (loop = 60)
         ->  Bitmap Heap Scan on result_table_child_70 a  (cost=8.82..1026.73 rows=783 width=48) (actual time=5.181..29.068 rows=34640 loops=1)
               Recheck Cond: (loop = 60)
               ->  Bitmap Index Scan on resultTable_child_70_idx (cost=0.00..8.63 rows=783 width=0) (actual time=4.843..4.843 rows=34640 loops=1)
                     Index Cond: (loop = 60)
 Total runtime: 220128.290 ms

После анализа таблицы и установки enable_bitmapscan = off (по-прежнему используется разбиение):

 Result  (cost=0.00..2761.06 rows=33652 width=389) (actual time=9.714..378389.177 rows=34640 loops=1)
   ->  Append  (cost=0.00..2676.93 rows=33652 width=389) (actual time=0.119..34.065 rows=34640 loops=1)
         ->  Index Scan using "resultTable_idx_mo" on resultTable a  (cost=0.00..12.84 rows=5 width=48) (actual time=0.058..0.058 rows=0 loops=1)
               Index Cond: (loop= 79)
         ->  Index Scan using resultTable_child_80_idx on resultTable_child_80 a  (cost=0.00..2664.10 rows=33647 width=389) (actual time=0.061..30.303 rows=34640 loops=1)
               Index Cond: (loop = 79)
 Total runtime: 378393.671 ms
(7 rows)

Ответы [ 2 ]

4 голосов
/ 13 марта 2012

Если кластеризация и разбиение не работают, я начинаю подозревать, что у вас есть серьезные проблемы с вашей системой хранения.10 секунд для сканирования кучи 35К строк на несколько порядков медленнее.Какую версию Postgres вы используете?Как выглядит ваше хранилище?Проверьте свои iostats.

Я организовал эксперимент на маленькой виртуальной машине (1 дробный процессор, 1 Гб памяти, монтирование диска NFS) с Pg 9.0.4, создавая вашу таблицу и индекс и добавляя 1000 пакетов по 36000 записей в каждой.

insert into r(loop,value,xfrom,xto,material,transport,pk) select 0,0,0,0,0,0,i from generate_series(0,35999) i;
insert into r(loop,value,xfrom,xto,material,transport,pk) select 1,0,0,0,0,0,i from generate_series(36000,71999) i;
...

Выполнение выбора в любом пакете не должно превышать 40 мсек:

explain analyze select exp(least(709,a.value)), a.xfrom, a.xto, a.material,a.transport from r a where a.loop=31;
 Index Scan using "resultTable_idx_mo" on r a  (cost=0.00..1596.35 rows=37680 width=21) (actual time=0.087..34.038 rows=36000 loops=1)
   Index Cond: (loop = 31)
 Total runtime: 36.332 ms

explain analyze select exp(least(709,a.value)), a.xfrom, a.xto,a.material,a.transport from r a where a.loop=87;
 Index Scan using "resultTable_idx_mo" on r a  (cost=0.00..1421.35 rows=33480 width=21) (actual time=0.105..37.357 rows=36000 loops=1)
   Index Cond: (loop = 87)
 Total runtime: 39.365 ms

Обратите внимание, что мои планы предусматривают использование обычного IndexScan вместо BitmapScans, а затем HeapScans.Вы внесли изменения в конфигурацию оптимизации плана, чтобы повлиять на план?

В ваших пояснениях я отмечаю, что предполагаемое количество строк намного меньше фактического количества строк (1649 против 34640).Это указывает на то, что у вас неточная статистика в таблице.Вам следует запустить ANAYLZE resultTable;

Я полагаю, что в вашей конфигурации postgres или в вашей системе хранения есть что-то не так, когда эти простые операции сканирования индекса занимают более нескольких десятков мс.Есть ли другая активность в этой базе данных, когда вы выполняете свои запросы?Возможно, ваши результаты - это конкуренция за ресурсы с другими запросами?

2 голосов
/ 13 марта 2012

Кластер, вероятно, ускорит его:

cluster resultTable using resultTable_idx_mo;

Но окончательным решением будет разделить вашу таблицу по циклу:

http://www.postgresql.org/docs/current/interactive/ddl-partitioning.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...