Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
Почему используется именно такой loop join?
|
|||
|---|---|---|---|
|
#18+
Тестирую на разных сценариях очередь. Есть две таблицы: queue, events Запрос на получение очередного события: Код: sql 1. 2. 3. 4. 5. 6. индекс events(queue) В таблице queue 2 записи, условию не удовлетворяет ни одна В таблице events 2 000 000 записей, все с q.queue=e.queue При запросе PG делает loop join с перебором по events, что занимает 2 секунды, хотя кажется логичнее делать по queue, с выбором подходящего из events по индексу. Что я делаю не так, как ускорить такой запрос? (Аналогичная проблема возникает, когда под условие подходит только одна запись в events, но с максимальным id - тоже приходится сканировать всю таблицу events по первичному ключу, что долго. Понятно, что если подходит запись в event с минимальным id, то все отрабатывает мгновенно и вообще в events обычно мало записей и подходящие находятся сразу, я в основном проверяю corner cases, но реальные). Заранее спасибо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.10.2016, 14:09 |
|
||
|
Почему используется именно такой loop join?
|
|||
|---|---|---|---|
|
#18+
DPH3Тестирую на разных сценариях очередь. Есть две таблицы: queue, events Запрос на получение очередного события: Код: sql 1. 2. 3. 4. 5. 6. индекс events(queue) В таблице queue 2 записи, условию не удовлетворяет ни одна В таблице events 2 000 000 записей, все с q.queue=e.queue При запросе PG делает loop join с перебором по events, что занимает 2 секунды, хотя кажется логичнее делать по queue, с выбором подходящего из events по индексу. Что я делаю не так, как ускорить такой запрос? (Аналогичная проблема возникает, когда под условие подходит только одна запись в events, но с максимальным id - тоже приходится сканировать всю таблицу events по первичному ключу, что долго. Понятно, что если подходит запись в event с минимальным id, то все отрабатывает мгновенно и вообще в events обычно мало записей и подходящие находятся сразу, я в основном проверяю corner cases, но реальные). Заранее спасибо. А если сделать analyze queue; - план не меняется? -- Maxim Boguk www.postgresql-consulting.ru ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.10.2016, 14:41 |
|
||
|
Почему используется именно такой loop join?
|
|||
|---|---|---|---|
|
#18+
Maxim Boguk, Нет, не меняется, увы ( ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.10.2016, 15:52 |
|
||
|
Почему используется именно такой loop join?
|
|||
|---|---|---|---|
|
#18+
DPH3Maxim Boguk, Нет, не меняется, увы ( 1)а что говори explain analyze на этот запрос? 2)сколько уникальных queue а таблице events ? PS: вообще привыкайте всегда все такие вопросы сопровождать результатом explain analyze. -- Maxim Boguk www.postgresql-consulting.ru ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.10.2016, 16:11 |
|
||
|
Почему используется именно такой loop join?
|
|||
|---|---|---|---|
|
#18+
Maxim Boguk, 1. explain analyze: "Limit (cost=0.43..0.54 rows=1 width=41) (actual time=1781.399..1781.399 rows=1 loops=1)" " -> LockRows (cost=0.43..137154.11 rows=1234680 width=41) (actual time=1781.399..1781.399 rows=1 loops=1)" " -> Nested Loop (cost=0.43..124807.31 rows=1234680 width=41) (actual time=1781.394..1781.394 rows=1 loops=1)" " Join Filter: ((q.queue)::text = (e.queue)::text)" " Rows Removed by Join Filter: 2469359" " -> Index Scan using events_pkey on wq_events e (cost=0.43..87765.87 rows=2469360 width=35) (actual time=0.038..1263.381 rows=2469360 loops=1)" " -> Materialize (cost=0.00..1.04 rows=1 width=15) (actual time=0.000..0.000 rows=1 loops=2469360)" " -> Seq Scan on queue q (cost=0.00..1.03 rows=1 width=15) (actual time=0.005..0.005 rows=1 loops=1)" " Filter: (((state)::text = 'RUNNING'::text))" " Rows Removed by Filter: 1" "Planning time: 0.606 ms" "Execution time: 1781.447 ms" 2. В данный момент два queue в events, в одном два значения, в другом - все остальные. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.10.2016, 16:58 |
|
||
|
Почему используется именно такой loop join?
|
|||
|---|---|---|---|
|
#18+
DPH3Maxim Boguk, 1. explain analyze: "Limit (cost=0.43..0.54 rows=1 width=41) (actual time=1781.399..1781.399 rows=1 loops=1)" " -> LockRows (cost=0.43..137154.11 rows=1234680 width=41) (actual time=1781.399..1781.399 rows=1 loops=1)" " -> Nested Loop (cost=0.43..124807.31 rows=1234680 width=41) (actual time=1781.394..1781.394 rows=1 loops=1)" " Join Filter: ((q.queue)::text = (e.queue)::text)" " Rows Removed by Join Filter: 2469359" " -> Index Scan using events_pkey on wq_events e (cost=0.43..87765.87 rows=2469360 width=35) (actual time=0.038..1263.381 rows=2469360 loops=1)" " -> Materialize (cost=0.00..1.04 rows=1 width=15) (actual time=0.000..0.000 rows=1 loops=2469360)" " -> Seq Scan on queue q (cost=0.00..1.03 rows=1 width=15) (actual time=0.005..0.005 rows=1 loops=1)" " Filter: (((state)::text = 'RUNNING'::text))" " Rows Removed by Filter: 1" "Planning time: 0.606 ms" "Execution time: 1781.447 ms" 2. В данный момент два queue в events, в одном два значения, в другом - все остальные. 1)Вы же написали что "В таблице queue 2 записи, условию не удовлетворяет ни одна" а у вас одна есть. 2)Нельзя построить единый план который бы работал нормально в вашей структуре данных. База предполагает что e.queue более менее поровну распределены по wq_events Поэтому база вполне честно считает что она быстро найдет нужную ей запись, а то что у вас данные сильно неровные - не делайте такие данные. Любой план будет плохо работать на corner cases и ничего вы с этим не сделаете. База из неких средне-нормальных вариантов план подбирает. -- Maxim Boguk www.postgresql-consulting.ru ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.10.2016, 17:31 |
|
||
|
Почему используется именно такой loop join?
|
|||
|---|---|---|---|
|
#18+
Maxim Boguk1)Вы же написали что "В таблице queue 2 записи, условию не удовлетворяет ни одна" а у вас одна есть. Когда нет ни одной подходящей - та же картинка, ничего не работает. 2)Нельзя построить единый план который бы работал нормально в вашей структуре данных. База предполагает что e.queue более менее поровну распределены по wq_events Поэтому база вполне честно считает что она быстро найдет нужную ей запись, а то что у вас данные сильно неровные - не делайте такие данные. Ок, понял, спасибо большое, буду думать. -- Maxim Boguk www.postgresql-consulting.ru [/quot] ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.10.2016, 18:14 |
|
||
|
Почему используется именно такой loop join?
|
|||
|---|---|---|---|
|
#18+
Maxim Boguk, если кваеев всегда мало (что модельно скорее всего так и есть), то нужен индекс (кваее,ивент) и переписать запрос на лейтерал по 50 записей из каждой кваее, с последующим фильтром 50 из отобранных вдоль ивент. (этому можно бы было и оптимайзер обучить, будь у них желание) ПС пгку вообще отдельные таблички ивентов под каждое кваее ведет, и очереди обрабатывает раздельно, без этого вот всего. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.10.2016, 18:14 |
|
||
|
Почему используется именно такой loop join?
|
|||
|---|---|---|---|
|
#18+
qwwqMaxim Boguk, если кваеев всегда мало (что модельно скорее всего так и есть), то нужен индекс (кваее,ивент) и переписать запрос на лейтерал по 50 1 записейи из каждой кваее, с последующим фильтром 50 1 из отобранных вдоль ивент. (ресорт) (этому можно бы было и оптимайзер обучить, будь у них желание) ПС пгку вообще отдельные таблички ивентов под каждое кваее ведет, и очереди обрабатывает раздельно, без этого вот всего. извиняюсь, поправил. всё смешалось в доме обломских(тм) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.10.2016, 18:20 |
|
||
|
Почему используется именно такой loop join?
|
|||
|---|---|---|---|
|
#18+
qwwqесли кваеев всегда мало (что модельно скорее всего так и есть), то нужен индекс (кваее,ивент) и переписать запрос на лейтерал по 50 записей из каждой кваее, с последующим фильтром 50 из отобранных вдоль ивент. Да это будет работать безусловно. Но вопрос стоял как ускорить именно такой запрос а не как переписать его по уму :). PS: автору топика - возьмите PGQ и не извращайтесь. Я пока не видел НИ ОДНОЙ нормальной самописной очереди на Postgres (а посмотрел я их много). -- Maxim Boguk www.postgresql-consulting.ru ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.10.2016, 18:38 |
|
||
|
Почему используется именно такой loop join?
|
|||
|---|---|---|---|
|
#18+
[quot Maxim Boguk] PS: автору топика - возьмите PGQ и не извращайтесь. Я пока не видел НИ ОДНОЙ нормальной самописной очереди на Postgres (а посмотрел я их много). [quot] Увы, в PGQ WorkQueue сделана несколько "сбоку", постоянно создавать и уничтожать очереди тоже не слишком дешево (а у меня по ТЗ до 100 очередей в секунду нужно создавать/удалять, да и очередей может быть очень много), отложенной обработки, насколько я помню, нет вообще, обработку ошибок делать тоже не слишком просто. Т.е. его можно взять за основу - но слишком много допиливать, текущее решение меня вполне устраивает, просто в некоторых сценариях ведет себя не лучшим способом. Я довольно много посмотрел вариантов, прежде чем велосипед пилить. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.10.2016, 03:07 |
|
||
|
Почему используется именно такой loop join?
|
|||
|---|---|---|---|
|
#18+
[quot DPH3][quot Maxim Boguk] PS: автору топика - возьмите PGQ и не извращайтесь. Я пока не видел НИ ОДНОЙ нормальной самописной очереди на Postgres (а посмотрел я их много). пропущено... Вот из-за case corners нормально ваше решение в режиме 100 очередей новых в секунду - работать никогда не будет. Вообще постоянное создание и drop очередей - это признак того что архитектурно что то не то делают. Т.е. pgq такой какой он есть именно для того чтобы работать быстро всегда (и таки да он работает быстро), а для этого в таблицах очереди не должно быть никаких странных аномалий с данными. -- Maxim Boguk www.postgresql-consulting.ru ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.10.2016, 03:57 |
|
||
|
Почему используется именно такой loop join?
|
|||
|---|---|---|---|
|
#18+
Maxim Boguk, ну, как раз на тех сценариях, где нужна работа с сотней очередей в секунду - все нормально работает. И как раз в тех сценариях, где PGQ без кучи сложных доработок вообще не пригоден. Просто не хочется для близких задач плодить разные решения - вот и смотрю, когда и для чего еще можно использовать ту же самую очередь. У PGQ все-таки довольно конкретная ниша для применения. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.10.2016, 12:53 |
|
||
|
|

start [/forum/topic.php?fid=53&fpage=84&tid=1996928]: |
0ms |
get settings: |
9ms |
get forum list: |
12ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
61ms |
get topic data: |
10ms |
get forum data: |
2ms |
get page messages: |
51ms |
get tp. blocked users: |
2ms |
| others: | 315ms |
| total: | 470ms |

| 0 / 0 |
