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 ответов

35 просмотров

из 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) показывали, или это я со своими планами перепутал? ;)

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

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

Господа, а что сейчас вообще с рынком труда на делфи происходит? Какова ситуация?
Rꙮman Yankꙮvsky
29
А вообще, что может смущать в самой Julia - бы сказал, что нет единого стандартного подхода по многим моментам, поэтому многое выглядит как "хаки" и произвол. Короче говоря, с...
Viktor G.
2
30500 за редактор? )
Владимир
47
а через ESC-код ?
Alexey Kulakov
29
Чёт не понял, я ж правильной функцией воспользовался чтобы вывести отладочную информацию? но что-то она не ловится
notme
18
У меня есть функция где происходит это: write_bit(buffer, 1); write_bit(buffer, 0); write_bit(buffer, 1); write_bit(buffer, 1); write_bit(buffer, 1); w...
~
14
Добрый день! Скажите пожалуйста, а какие программы вы бы рекомендовали написать для того, чтобы научиться управлять памятью? Можно написать динамический массив, можно связный ...
Филипп
7
Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
Ребят в СИ можно реализовать ООП?
Николай
33
https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_h_common.erl#L174 https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_olp.erl#L76 15 лет назад...
Maksim Lapshin
20
Карта сайта