powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Быстрый запрос в explain analyze но медленный по факту
15 сообщений из 65, страница 3 из 3
Быстрый запрос в explain analyze но медленный по факту
    #38922488
Фотография vyegorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
VerusK,

Я бы понизил shared_buffers до 2Гб, work_mem до 8Мб, effective_cache_size до 64Гб и пересобрал бы статистики.

Также я бы оставил commit_delay + commit_siblings по умолчанию.
...
Рейтинг: 0 / 0
Быстрый запрос в explain analyze но медленный по факту
    #38922503
Фотография vyegorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
VerusK,

Если читаете по-английски, то посмотрите этот пост .
...
Рейтинг: 0 / 0
Быстрый запрос в explain analyze но медленный по факту
    #38922673
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
VerusKВот код триггера, тут как раз создание дочерних таблиц - https://gist.github.com/anonymous/79d37e631892b4c2048f

а вот что попробуйте
вместо
Код: plaintext
1.
CHECK ( ts_spawn >= ' || ts_start || ' AND ts_spawn < ' || ts_end || '),
            CONSTRAINT ' || table_part || '_user_id CHECK (user_id = ' || NEW.user_id || ')

сделать один общий CHECK:
Код: plaintext
CHECK ( (ts_spawn >= ' || ts_start || ' AND ts_spawn < ' || ts_end || ') AND user_id = ' || NEW.user_id || '),

(причем на всех уже созданных партициях сменить тоже).

И посмотрите не исправилась ли ситуация.

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

--Maxim Boguk
www.postgresql-consulting.ru
...
Рейтинг: 0 / 0
Быстрый запрос в explain analyze но медленный по факту
    #38922719
PgSQLAnonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
VerusKvyegorov,

все запросы - https://gist.github.com/anonymous/90e84a06ab8bbe60f37e
Вам бы следовало дать хоть какой-то SQL-script для воспроизведения ситуации. :(

Я вот попробовал воспроизвести (упрощённо): http://sqlfiddle.com/#!15/9a9c2/2

Неудобство в том, что PostgreSQL там максимум 9.3, зато оттуда можно скопировать и попробовать у себя.
...
Рейтинг: 0 / 0
Быстрый запрос в explain analyze но медленный по факту
    #38922848
VerusK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Maxim Boguk, попробовать можно, но не скоро, надо подумать как этот процесс автоматизировать. Руками нереально :)

PgSQLAnonymous, это если только дать дамп всех таблиц, там много записей уже, sqlfiddle отказывается столько заполнять :)
...
Рейтинг: 0 / 0
Быстрый запрос в explain analyze но медленный по факту
    #38922858
VerusK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
А если попробовать написать триггер на update? Т.е. в триггере указывать в какой конкретно таблице надо проапдейтить запись. Наткнулся вот на такое обсуждение - http://postgresql.nabble.com/Query-plan-for-partitioned-UPDATE-DELETE-slow-and-swaps-vmem-compared-to-SELECT-td3291659.html
может с 2010 в этом плане ничего и не изменилось? :(
...
Рейтинг: 0 / 0
Быстрый запрос в explain analyze но медленный по факту
    #38922920
йоксель
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
VerusKА если попробовать написать триггер на update? Т.е. в триггере указывать в какой конкретно таблице надо проапдейтить запись. Наткнулся вот на такое обсуждение - http://postgresql.nabble.com/Query-plan-for-partitioned-UPDATE-DELETE-slow-and-swaps-vmem-compared-to-SELECT-td3291659.html
может с 2010 в этом плане ничего и не изменилось? :(как вы себе представляете событие данных в таблице, в которой их нет ?

или вы на стейтмент хотите триггер повесить ?

я вам попытался предложить тестирование альтернативы -- делаете наследников 2-х уровней. пустышки по первому чеку, им наследуете реальные таблицы с первым наследуемым и вторым чеком -- просто проверить, как идет пеербор чеков -- сразу на всю глубину иерархии, или умнее. скорее всего не выгорит. но может и полететь

а обход иерархий скриптом -- стандартная задача
...
Рейтинг: 0 / 0
Быстрый запрос в explain analyze но медленный по факту
    #38923111
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vyegorovMaxim Boguk1)И так... prepared запрос планируется на этапе когда параметры запроса еще не известны.
2)В случае партиционирования это приводит к тому что план ВСЕГДА будет включать в себя обработку всех партиций,
так как построить универсальный план по другому - невозможно.

Начиная с версии 9.2 PostgreSQL поддерживает параметризованные подготовленные запросы (вторая звездочка).

Другое дело, что были жалобы (я не смогу найти быстро), что первые 4 исполнения проходят быстро, а потом планировщик переклинивает и он выбирает не оптимальные планы. Вроде эта тема была закрыта (патчами).

В связи с этим 2 вопроса:
какие конкретно версии (интересуют все 3 цифры) вы тестировали? в смысле — все ли апдейты стоят?

каким будет поведение на 9.1?


Тут коротко на этот вопрос не ответишь.

Часть1:
Как работают параметризованные prepared запросы - строятся 2 плана общий в начале и частный с учетом параметров при первом вызове.
Далее пока данный prepared запрос работает только с теми параметрами которые подходят под частный план - все в теории хорошо, но стоит 1 раз вызвать этот же prepared запрос с другими параметрами как он НЕОБРАТИМО переключится на generic plan и будет его использовать все время жизни prepared запроса. Иногда это приводит к милым эффектам - вот есть большое java приложение, вот оно сделало prepared запрос для какой то большой партиционированной таблицы. Далее 99.999% случаев запросы работают с текущим месяцем данные которого успешно закешированны в базе, потом какой то менеджер решает случайно посмотреть данные за прошлый месяц и тут наступает ад, так как этот prepared запрос (а они в java Дооолго живут) начинает перебирать архив партиций с данными за последние 10 лет которые лежат на медленных SAS дисках просто для истории, а он может вызываться часто. Вот так сервер работал-работал и упс. Я такую проблему как то 2 недели ловил.

Часть2:
Касательно " в теории хорошо" - на практике в 9.2.10 (последнем) поведение следующее у меня получается:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
prepare test(timestamp, integer) as select * from resstat where to_date=$1  and lbill_id=$2 limit 10;
PREPARE

 explain analyze execute test('2015-03-03 00:00:00'::timestamp, 1000);
                                                                                QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 Limit  (cost=0.00..20.24 rows=2 width=100) (actual time=0.088..0.088 rows=0 loops=1)
   ->  Result  (cost=0.00..20.24 rows=2 width=100) (actual time=0.085..0.085 rows=0 loops=1)
         ->  Append  (cost=0.00..20.24 rows=2 width=100) (actual time=0.084..0.084 rows=0 loops=1)
               ->  Seq Scan on resstat  (cost=0.00..0.00 rows=1 width=116) (actual time=0.002..0.002 rows=0 loops=1)
                     Filter: ((to_date = '2015-03-03 00:00:00'::timestamp without time zone) AND (lbill_id = 1000))
               ->  Index Scan using resstat_2015_03_lbill_id_idx on resstat_2015_03 resstat  (cost=0.00..20.24 rows=1 width=83) (actual time=0.082..0.082 rows=0 loops=1)
                     Index Cond: (lbill_id = 1000)
                     Filter: (to_date = '2015-03-03 00:00:00'::timestamp without time zone)
 Total runtime: 9.192 ms

так повторяется  5 раз... на 6 раз получается план перебтирающий все партции (6 лет архива), и остается таким до победы.
billing=# explain analyze execute test('2015-03-03 00:00:00'::timestamp, 1000);
                                                                                QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 Limit  (cost=0.00..184.76 rows=10 width=83) (actual time=1.570..1.570 rows=0 loops=1)
   ->  Result  (cost=0.00..2900.68 rows=157 width=83) (actual time=1.566..1.566 rows=0 loops=1)
         ->  Append  (cost=0.00..2900.68 rows=157 width=83) (actual time=1.565..1.565 rows=0 loops=1)
               ->  Seq Scan on resstat  (cost=0.00..0.00 rows=1 width=116) (actual time=0.002..0.002 rows=0 loops=1)
                     Filter: ((to_date = $1) AND (lbill_id = $2))
               ->  Index Scan using idx_resstat_2009_01_lbill_id on resstat_2009_01 resstat  (cost=0.00..23.30 rows=1 width=80) (actual time=0.035..0.035 rows=0 loops=1)
                     Index Cond: (lbill_id = $2)
                     Filter: (to_date = $1)
               ->  Index Scan using idx_resstat_2009_02_lbill_id on resstat_2009_02 resstat  (cost=0.00..23.59 rows=1 width=80) (actual time=0.013..0.013 rows=0 loops=1)
                     Index Cond: (lbill_id = $2)
                     Filter: (to_date = $1)
....

Так что проблему не исправили. Что в сочетании с изложенным в Часть1 делает лобовое использование партиций в сочетании с prepared запросами наработоспособным. Увы.

PS: пойду bug report напишу.

--Maxim Boguk
www.postgresql-consulting.ru
...
Рейтинг: 0 / 0
Быстрый запрос в explain analyze но медленный по факту
    #38923146
PgSQLAnonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
VerusKPgSQLAnonymous, это если только дать дамп всех таблиц, там много записей уже, sqlfiddle отказывается столько заполнять :)

А я вот погонял тот fiddle, на который давал ссылку, на своём Postgres-е, и у меня Ваша проблема-то воспроизводится. ;)

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
EXPLAIN ANALYZE 
 UPDATE stats SET actions = 2
  WHERE stats.ts_spawn = 1400000000 AND stats.user_id = 2
    AND stats.offer_targeting_id = 132 AND stats.offer_id = 123
    AND stats.traff_type = 4 AND stats.operator_id = 0
    AND stats.country_id = 113 AND stats.subacc_1 = '' AND stats.subacc_2 = ''
    AND stats.subacc_3 = '' AND stats.subacc_4 = '' AND stats.utm_source = ''
    AND stats.utm_medium = '' AND stats.utm_term = ''
    AND stats.utm_content = '' AND stats.utm_campaign = ''
    AND stats.prelanding_id = 203 AND stats.landing_id = 0
    AND stats.platform_id = 6 AND stats.platform_out_id = 76 
    AND stats.os_id = 9 AND stats.browser_id = 34;


Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
 Update on stats  (cost=0.00..8.21 rows=2 width=666) (actual time=0.030..0.030 rows=0 loops=1)
   ->  Seq Scan on stats  (cost=0.00..0.00 rows=1 width=666) (actual time=0.003..0.003 rows=0 loops=1)
         Filter: ((ts_spawn = 1400000000) AND (user_id = 2) AND (offer_targeting_id = 132) AND (offer_id = 123) AND (traff_type = 4) AND (operator_id = 0) AND (landing_id = 0) AND (country_id = 113) AND ((subacc_1)::text = ''::text) AND ((subacc_2)::text = ''::text) AND ((subacc_3)::text = ''::text) AND ((subacc_4)::text = ''::text) AND ((utm_source)::text = ''::text) AND ((utm_medium)::text = ''::text) AND ((utm_term)::text = ''::text) AND ((utm_content)::text = ''::text) AND ((utm_campaign)::text = ''::text) AND (prelanding_id = 203) AND (platform_id = 6) AND (platform_out_id = 76) AND (os_id = 9) AND (browser_id = 34))
   ->  Index Scan using idx_stats_y2014_m5_u2_browser_id on stats_y2014_m5_u2  (cost=0.14..8.21 rows=1 width=666) (actual time=0.017..0.017 rows=0 loops=1)
         Index Cond: (browser_id = 34)
         Filter: ((ts_spawn = 1400000000) AND (user_id = 2) AND (offer_targeting_id = 132) AND (offer_id = 123) AND (traff_type = 4) AND (operator_id = 0) AND (landing_id = 0) AND (country_id = 113) AND ((subacc_1)::text = ''::text) AND ((subacc_2)::text = ''::text) AND ((subacc_3)::text = ''::text) AND ((subacc_4)::text = ''::text) AND ((utm_source)::text = ''::text) AND ((utm_medium)::text = ''::text) AND ((utm_term)::text = ''::text) AND ((utm_content)::text = ''::text) AND ((utm_campaign)::text = ''::text) AND (prelanding_id = 203) AND (platform_id = 6) AND (platform_out_id = 76) AND (os_id = 9))
  Planning time: 139.502 ms 
 Execution time: 0.504 ms

Это при том, что у stats всего 61 partition и по одной записи в каждой из них.

Это PostgreSQL 9.4.1.
...
Рейтинг: 0 / 0
Быстрый запрос в explain analyze но медленный по факту
    #38923152
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PgSQLAnonymous,

Текущая теория что партиционирование по 2м чекам приводит к каким то проблемам с планированием.
Попробую сделать короткий test case и зарепортить bug (если test case получится конечно)


--Maxim Boguk
www.postgresql-consulting.ru
...
Рейтинг: 0 / 0
Быстрый запрос в explain analyze но медленный по факту
    #38923157
Фотография vyegorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Maxim Boguk,

Спасибо за подробный ответ. Давно думаю, что отчасти из-за таких же проблем оракл свой шаред_пул сделал (там, правда, свои грабли).

Эх, не исправят они эту фишку пока полноценные партиции не прикрутят.
...
Рейтинг: 0 / 0
Быстрый запрос в explain analyze но медленный по факту
    #38923163
PgSQLAnonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Maxim BogukPgSQLAnonymous,
Текущая теория что партиционирование по 2м чекам приводит к каким то проблемам с планированием.
Попробую сделать короткий test case и зарепортить bug (если test case получится конечно)


Хм... А чем Вам этот fiddle не подходит как test case? Кстати, при 155 таблицах уже:
Planning time: 534.810 ms
...
Рейтинг: 0 / 0
Быстрый запрос в explain analyze но медленный по факту
    #38923164
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Maxim BogukPgSQLAnonymous,

Текущая теория что партиционирование по 2м чекам приводит к каким то проблемам с планированием.
Попробую сделать короткий test case и зарепортить bug (если test case получится конечно)


--Maxim Boguk
www.postgresql-consulting.ru

по моим экспериментам получилось что проблема не столько в партициях сколько в 60*25 = 1500 индексах в плане.
без 25 индексов на каждой таблице запрос планируется раз в 10 быстрее что уже ближе к правде.

--Maxim Boguk
www.postgresql-consulting.ru
...
Рейтинг: 0 / 0
Быстрый запрос в explain analyze но медленный по факту
    #38923218
VerusK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Кстати, в другом проекте использовал партиционирование по одному чеку - таких проблем там не наблюдается, проверил(PG 9.3). Убрать тут чеки для тестов со всех таблиц еще не успел :)
...
Рейтинг: 0 / 0
Быстрый запрос в explain analyze но медленный по факту
    #38923664
VerusK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Пока остановился на решении в приложении указывать нужную партицию если это update. Теперь вставка происходит значительно быстрее.
...
Рейтинг: 0 / 0
15 сообщений из 65, страница 3 из 3
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Быстрый запрос в explain analyze но медленный по факту
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]