172 похожих чатов

А можно как-то ускорить unnest? select unnest(p."attrs") from product_v2 p where

p."attrs" @> '{337}'

+------------------------------------------------------------------------------------------------------------------------------------------+
|QUERY PLAN |
+------------------------------------------------------------------------------------------------------------------------------------------+
|ProjectSet (cost=73.00..5004.83 rows=58060 width=4) (actual time=0.841..316.285 rows=155400 loops=1) |
| Output: unnest(attrs) |
| -> Bitmap Heap Scan on public.product_v2 p (cost=73.00..4670.98 rows=5806 width=92) (actual time=0.836..16.179 rows=5974 loops=1) |
| Output: attrs |
| Recheck Cond: (p.attrs @> '{337}'::integer[]) |
| Heap Blocks: exact=3245 |
| -> Bitmap Index Scan on product_v2_attrs_index (cost=0.00..71.55 rows=5806 width=0) (actual time=0.543..0.545 rows=5974 loops=1)|
| Index Cond: (p.attrs @> '{337}'::integer[]) |
|Planning Time: 0.070 ms |
|Execution Time: 598.275 ms |
+------------------------------------------------------------------------------------------------------------------------------------------+

19 ответов

18 просмотров

из 6т записей получаешь 155т. не думаю, что тут можно что-то радикально ускорить

Без переписывания кода постгреса -- это не слишком вероятно. (Лучшэ избавиться от необходимости unnest. Перенести его в код приложэния, если обработка на сервере не нужна -- либо нормализовать базу, если нужна).

Roman-Timofeev Автор вопроса

Нормализация делает больно + усложняет выборки

Roman Timofeev
Нормализация делает больно + усложняет выборки

Это заблуждение, делает больно в основном хранение данных в виде массивов

А какая версия PostgreSQL ( SELECT version(); ) и распределение количества элементов в массивах? Потому что (у меня v15.3) вот это: CREATE UNLOGGED TABLE product_v2 ( id bigint NOT NULL , attrs int[] NOT NULL ); INSERT INTO product_v2(id, attrs) SELECT 1 + n / 28 AS id, array_agg(n / 6000 + n % 800) FROM generate_series(1, 8000000) AS g(n) GROUP BY 1 ORDER BY id; CREATE INDEX ON product_v2 USING gin(attrs); VACUUM ANALYZE product_v2; Даёт вот такой план: ProjectSet (cost=55.46..6496.08 rows=50920 width=4) (actual time=4.158..16.461 rows=142576 loops=1) Output: unnest(attrs) -> Bitmap Heap Scan on public.product_v2 p (cost=55.46..6203.29 rows=5092 width=135) (actual time=4.146..8.404 rows=5092 loops=1) Output: id, attrs Recheck Cond: (p.attrs @> '{678}'::integer[]) Heap Blocks: exact=3096 -> Bitmap Index Scan on product_v2_attrs_idx (cost=0.00..54.19 rows=5092 width=0) (actual time=2.400..2.400 rows=5092 loops=1) Index Cond: (p.attrs @> '{678}'::integer[]) Planning Time: 0.397 ms Execution Time: 19.457 ms Обратите внимание, что почти все числа очень близки к Вашему (или даже немного хуже). А вот именно время unnest() почему-то сильно отличается (поэтому и вопросы выше).

Roman Timofeev
15.3

Странно. А по второму вопросу (может, там сильно разное количество элементов в разных записях, а не по ≈ 28, как в моём примере)? Ну и Вы можете просто попробовать показанный пример у себя — сравнимое получится время исполнения или совсем другое?

Roman-Timofeev Автор вопроса
Yaroslav Schekin
Странно. А по второму вопросу (может, там сильно р...

+--------------------------------------------------------------------------------------------------------------------------------------------+ |QUERY PLAN | +--------------------------------------------------------------------------------------------------------------------------------------------+ |Gather (cost=1000.00..9233.88 rows=5371 width=4) (actual time=0.177..472.081 rows=142576 loops=1) | | Output: (unnest(attrs)) | | Workers Planned: 2 | | Workers Launched: 2 | | -> ProjectSet (cost=0.00..7696.78 rows=22380 width=4) (actual time=0.020..194.753 rows=47525 loops=3) | | Output: unnest(attrs) | | Worker 0: actual time=0.020..282.544 rows=69328 loops=1 | | Worker 1: actual time=0.019..289.857 rows=70700 loops=1 | | -> Parallel Seq Scan on public.product_v2 p (cost=0.00..7568.10 rows=2238 width=136) (actual time=0.014..27.503 rows=1697 loops=3)| | Output: id, attrs | | Filter: (p.attrs @> '{678}'::integer[]) | | Rows Removed by Filter: 93541 | | Worker 0: actual time=0.013..39.872 rows=2476 loops=1 | | Worker 1: actual time=0.014..36.161 rows=2525 loops=1 | |Planning Time: 0.060 ms | |Execution Time: 919.878 ms | +--------------------------------------------------------------------------------------------------------------------------------------------+ кверя select unnest(p."attrs") from product_v2 p where p."attrs" @> '{678}'

Roman Timofeev
+-------------------------------------------------...

А Вы точно выполнили VACCUM ANALYZE (какие-то оценки совсем косые, и вид плана другой — видимо, из-за этого)? В любом случае, для тестирования можно SET enable_seqscan = off (ну и/или отключить параллелизм), чтобы план получился такой же. Тем не менее, уже кажется, что что-то сильно не так...

Roman-Timofeev Автор вопроса
Yaroslav Schekin
А Вы точно выполнили VACCUM ANALYZE (какие-то оцен...

Ок, позвал ещё раз VACUUM ANALYZE. Стало лучше +----------------------------------------------------------------------------------------------------------------------------------------+ |QUERY PLAN | +----------------------------------------------------------------------------------------------------------------------------------------+ |ProjectSet (cost=58.15..6607.32 rows=54380 width=4) (actual time=0.788..293.715 rows=142576 loops=1) | | Output: unnest(attrs) | | -> Bitmap Heap Scan on public.product_v2 p (cost=58.15..6294.63 rows=5438 width=136) (actual time=0.777..14.200 rows=5092 loops=1) | | Output: id, attrs | | Recheck Cond: (p.attrs @> '{678}'::integer[]) | | Heap Blocks: exact=3096 | | -> Bitmap Index Scan on product_v2_attrs_idx (cost=0.00..56.79 rows=5438 width=0) (actual time=0.492..0.494 rows=5092 loops=1)| | Index Cond: (p.attrs @> '{678}'::integer[]) | |Planning Time: 0.068 ms | |Execution Time: 554.375 ms | +----------------------------------------------------------------------------------------------------------------------------------------+

Roman Timofeev
Ок, позвал ещё раз VACUUM ANALYZE. Стало лучше +-...

Т.е. получается: ProjectSet (cost=58.15..6607.32 rows=54380 width=4) (actual time=0.788..293.715 rows=142576 loops=1) -- у Вас ProjectSet (cost=55.46..6496.08 rows=50920 width=4) (actual time=4.158..16.461 rows=142576 loops=1) -- у меня Хмм... да не может быть моё [очень] старое "железо" почти в 20 раз лучше Вашего. ;) Может, там какая-то throttled ("зажатая" по ресурсам или с кем-то их делящая так, что ей почти ничего не остаётся) VM, или что-то в этом роде? В общем, мне кажется, что стоит в эту сторону посмотреть для начала.

Yaroslav Schekin
А какая версия PostgreSQL ( SELECT version(); ) и ...

Мне любопытно -- что на том хосте говорит cat /proc/cpuinfo (Похожэ, L2 кэш мегабайт 8).

Roman-Timofeev Автор вопроса
Ilya Anfimov
Мне любопытно -- что на том хосте говорит cat /pro...

Это мой ноут, но там Ryzen 7 4800HS и SSD, а сам pg не в контейнере.

Roman Timofeev
Это мой ноут, но там Ryzen 7 4800HS и SSD, а сам p...

Мне любопытнее было -- что у Ярослава. Но про седьмой мобильный райзен тожэ понял, спасибо.

Roman Timofeev
Это мой ноут, но там Ryzen 7 4800HS и SSD, а сам p...

Кстатида, надо на ноуте тожэ попробовать. (Так-то почти везде у меня -- unnest в этом запросе в 5 раз медленнее, чем выборка. В 20 на ноуте -- понятно. А вот где всего вдвое? Точнее, дажэ примерно той жэ скорости?)

Roman Timofeev
Это мой ноут, но там Ryzen 7 4800HS и SSD, а сам p...

По крайней мере SSD тут ни при чём — тест-то именно в RAM. Казалось бы (но я уже давно не разбираюсь в процессорах!), Ваш должен быть +- то же самое на single thread (но поновее)... может, performance profile (или как там оно называется в Вашем дистрибутиве) не так настроен?

Roman Timofeev
Это мой ноут, но там Ryzen 7 4800HS и SSD, а сам p...

Хотя подождите, что это я (по поводу SSD)... а Вы EXPLAIN (ANALYZE, BUFFERS) показывали, или это я со своими планами перепутал? ;)

Похожие вопросы

Обсуждают сегодня

И к какой архитектуре привязана Java?
Dmitry Olshansky
17
@Aiwan что такое база образца?
Alexey
27
Не многие знают, а кто знает, тот уже успел забыть, что в далёком 2004 году эта игра произвела настоящий фурор, настолько революционной была технология, применяемая для её соз...
ICCID
4
коллеги, добрый вечер! А никто не знает как модальная форма может себя закрыть? Ну допустим модальная форма определила, что смысла ей работать нет и хочет вернуть modalResult...
Михаил
83
Короче я тут узнал полный пиздец Что кучу постов которые я создавал через posted Спустя время не могу редактировать и менять Мол телега возвращае ошибку Это реально так ...
inc.
13
Хотя у меня сейчас есть более сложная задача, вот её думаю: как объяснить челу переходного возраста противоположного полу, обучающегося в польском колледже (а-ля наш техникум)...
Вячеслав Кузьменко
15
Добрый день Хочу начать обучение языку, не являюсь представителем it, буду благодарна за помощь, совсем пока не понимаю ничего) Подскажите, пожалуйста, где можно начать первы...
Sara Lala
30
а сколько всего в IT умерло? Где флеш-игры, их было туча, где они все? Сегодня технология есть, а завтра вжух и мёртвая. Этот wasm сильно напоминает джавовские апплеты, silver...
Constantin F.
5
а вы в курсе, что Initialize() не работает? var arr123: array[0..123] of Byte; ... Initialize(arr123, SizeOf(arr123));
Iluha Companets
8
верно что я могу удалить эти addq и subq т.к. со стеком никакого взаимодействия нет (исключая call)?
Michael
16
Карта сайта