Показаны сообщения с ярлыком optimization. Показать все сообщения
Показаны сообщения с ярлыком optimization. Показать все сообщения

Удивительная оптимизация получения distinct values из индекса, а также TopN для каждого

1 коммент.

Несколько дней назад на форуме задали, как изначально показалось, старый, скучный, вдоль и поперек изъезженный вопрос:
Есть лента новостей. Все новости разделены на 10 категорий(Политика, спорт, авто, недвижимость и тд).
Надо 1 запросом для каждой категории выбрать 4 новости.
Получается если перебрать результат - сразу идет 4 новости о политике, затем 4 новости о спорте и тд.
Однако, задача стояла - сделать это оптимально, а стандартное решение с обычным TopN через row_number никак оптимальным не назвать, особенно в случае больших таблиц, относительно небольшого количества категорий и неравномерного распределения или просто общей низкой селективности. И вот после нескольких более-менее хороших вариантов, подглядев в решение с PostgreSQL(правда я в нем не стал сильно разбираться, достаточно было увидеть рекурсию, min и предикат), получился отличный вариант.

Но обо всем по порядку:

1. Получение distinct значений из индекса

Большое количество latch free: dml allocation latch при конкурентных запросах к v$lock

0 коммент.

Проблема эта в общем-то старая, но только сейчас благодаря книге "Oracle Core" Джонатана Льюиса удалось узнать в чем собственно проблема и справиться с ней.
Цитата из главы "Latches for lock":

If the enqueue resource is in place already, then pick a row from the relevant enqueue structure (x$ksqeq, et al.), but to do this you have to get the associated enqueue latch to stop other people from picking the same enqueue row at the same time. The latch you need to acquire depends on the specific type of enqueue you are using; for example, if you want a row from x$ksqeq you need to get the enqueue latch but for a row from x$ktadm you need to get the dml allocation latch. Drop this latch as soon as you have made the enqueue row safe.