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

Вопрос вроде популярный, но не смог найти ошибку в решении.

Нужно вытащить последнюю реинкарнацию организации - с максимальной org_version для данной org_id Почему postgres настолько ошибается в оценках и как сделать чтоб не ошибался?
rdb=# \d tt
Table "public.tt"
Column | Type | Collation | Nullable | Default
-------------+---------+-----------+----------+---------
org_id | integer | | |
org_version | integer | | |
Indexes:
"tt_id_version" btree (org_id, org_version)

rdb=#
rdb=# explain (buffers,analyze)
select * from tt d1,
(select org.org_id,
max(org.org_version) AS max_org_version
FROM tt org
WHERE org.org_id >= 0 GROUP by org.org_id) d2
where d1.org_id = d2.org_id and d1.org_version = d2.max_org_version;
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------
Hash Join (cost=56.28..80.23 rows=6 width=16) (actual time=0.609..0.869 rows=847 loops=1)
Hash Cond: ((d1.org_id = org.org_id) AND (d1.org_version = (max(org.org_version))))
Buffers: shared hit=12
-> Seq Scan on tt d1 (cost=0.00..17.77 rows=1177 width=8) (actual time=0.012..0.074 rows=1177 loops=1)
Buffers: shared hit=6
-> Hash (cost=43.56..43.56 rows=848 width=8) (actual time=0.587..0.588 rows=847 loops=1)
Buckets: 1024 Batches: 1 Memory Usage: 42kB
Buffers: shared hit=6
-> HashAggregate (cost=26.60..35.08 rows=848 width=8) (actual time=0.391..0.485 rows=847 loops=1)
Group Key: org.org_id
Batches: 1 Memory Usage: 169kB
Buffers: shared hit=6
-> Seq Scan on tt org (cost=0.00..20.71 rows=1177 width=8) (actual time=0.007..0.128 rows=1176 loops=1)
Filter: (org_id >= 0)
Rows Removed by Filter: 1
Buffers: shared hit=6
Planning:
Buffers: shared hit=3
Planning Time: 0.352 ms
Execution Time: 0.959 ms
(20 rows)

rdb=#

17 ответов

18 просмотров

И Вы нашли для этого один из наихудших способов. ;( Почему бы не попробовать что-то получше (LATERAL, если есть таблица организаций; loose index scan (rCTE) или DISTINCT ON, если нет)? И, кстати, что б ему и не ошибаться в этом случае (в таблице даже ни одного ключа нет)? ;)

Sergey-Gr Автор вопроса
Yaroslav Schekin
И Вы нашли для этого один из наихудших способов. ;...

Я вот эти все извращения не очень понимаю. Но даже если сделать уникальный индекс на оба поля - всё равно ошибается. Надо объявить его как Primary Key?

Sergey Gr
Я вот эти все извращения не очень понимаю. Но даже...

Не понимаете — сидите с [в среднем так бывает] производительностью на два порядка (или более) худшей, чем могла бы быть — дело Ваше. ;( > всё равно ошибается. А ANALYZE выполняли? И вообще, это план на реальных данных (иначе обсуждать это я практического смысла не вижу)?

Sergey-Gr Автор вопроса
Yaroslav Schekin
Не понимаете — сидите с [в среднем так бывает] пр...

В реальности таблица шире, число строк точное. Analyze делал

Sergey Gr
В реальности таблица шире, число строк точное. Ana...

Тогда нужно копаться с конкретными данными и смотреть, как планировщик оценивает этот JOIN (но "чудо" там вряд ли будет — подобные оценки в принципе довольно грубы)...

Yaroslav Schekin
И Вы нашли для этого один из наихудших способов. ;...

А, собственно, почему? По-моему, как в его случае (когда org_version в среднем не сильно большэ одного на org_id) -- вменяемый довольно способ. Хотя, конечно... Планировщик за такое спасибо не скажэт.

Зачем для каждой организации свой счетчик, можно же сделать один на всех и брать его max + фильтр по org_id?

Ilya Anfimov
А, собственно, почему? По-моему, как в его случае...

Потому что объективные измерения (benchmarks) альтернативных способов (даже для разных распределений данных) показывают, что это так — погуглите или попробуйте.

Кстати, если чаще всего нужэн максимальный org_version -- то имеет смысл начинать с создания индэкса (org_id, org_version DESC) Чуть-чуть быстрее будут типичные операцыи и чуть-чуть лояльнее к нему отнесётся планировщик.

Yaroslav Schekin
Не понимаете — сидите с [в среднем так бывает] пр...

Да на какие два порядка, не будет там 10мкс на 1000 строк хоть обпишысь...

Yaroslav Schekin
И Вы нашли для этого один из наихудших способов. ;...

Кстати, я правильно помню, что самый поддержываемый синтаксисом DISTINCT ON -- до сих пор не умеет index skip scan?

Yaroslav Schekin
И Вы нашли для этого один из наихудших способов. ;...

И, в итоге, самый быстрый результат таких запросов -- пишэтся через WITH RECURSIVE ? (Но и то -- не за счёт того, что планировщик там что-то понимает, а как раз наоборот).

Ilya Anfimov
Да на какие два порядка, не будет там 10мкс на 100...

Где я говорил именно про 1000 строк?! Я написал "в среднем так бывает", безотносительно к конкретному примеру (я вообще подумал, что это просто тестовые данные / демонстрация).

Ilya Anfimov
Кстати, я правильно помню, что самый поддержываемы...

Так такого executor node до сих пор не существует — как он может его "уметь"? ;(

Ilya Anfimov
И, в итоге, самый быстрый результат таких запросов...

Самый быстрый (в норме) — LATERAL (или DISTINCT ON, если на каждое значение... org_id, в этом случае, приходится только 2-3 rows).

Ну, мало ли... На WITH RECURSIVE разложыть, например... Да и вообще. Есть многое на свете, друг Горацый, что мне лично и не снилось.

Ilya Anfimov
Ну, мало ли... На WITH RECURSIVE разложыть, наприм...

Не, все ждут, пока https://wiki.postgresql.org/wiki/Loose_indexscan кто-то "честно" реализует, зачем нам полумеры? ;)

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

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

А как старый хаскел с новым стыковать ? потому как тут работает https://play.haskell.org/saved/C3xpMzcd, а вот тут https://stepik.org/lesson/7602/step/9?unit=1473 нет ошибка C...
Fedor
131
Народ, кто шарит в расширенных разделах (EBR/EPR) на дисках с разметками MBR? Везде пишут (в вики рус/англ) в частности + другие источники смотрел, что первый сектор расширенн...
Eugene Krasnikov (ᴊɪɴ x)
1
что насчет пагинга? на осдеве непонятно(
Vi Chapmann 🪙
26
Вопрос я правильно понимаю что в коде newtype ArrowMap k v = ArrowMap { getArrowMap :: k -> Maybe v } getArrowMap есть функция типа k -> Maybe v, если да, то не понимаю задач...
Fedor
64
Ребят, что лучше для реверса: гидра или ида?
En Vind Av Sorg
26
Делаю велосипед логгер. К сообщению хочу прикрутить некоторую информацию, типа, кем отправлено, какой уровень, и всякое такое. И тут подумалось мне, почему бы не хранить весь...
Serjone
24
Как Вы считаете нормально ли в двадцатых годах 21 века в ВУЗах Российской Федерации обучать студентов работе с TASM? Не слишком ли это "архаично"? (Если оффтоп или флейм для э...
Spiker01
52
Всем привет! Использую gitlab-ci. Настроил gitlab-agent для деплоя в куб. При деплое проекта в логах такая ошибка: Executing deploy plan failed to watch "ns:my-project/Ingress...
Konstantin Moiseev
4
Комрады, хотел уточнить. Проперть в OnDestroy юнита-хозяина по-прежнему доступна? И еще уточнение: finalization юнита наступает раньше или позже OnDestroy?
Ed Doc
48
Продолжая диалог про свифт в проде – сейчас возник вопрос в активном наборе бекендеров. В основном в нашей компании мы фанаты Java Spring и полностью ей довольны. Однако найм ...
Guseyn
27
Карта сайта