Alexey Popov wrote:

Есть запрос вида

select ... from EVENTS
where a>:a and b=:b
order by a

Композитный индекс нормально использует если написать
order by b,a
Очевидно оптимизатор не понимает, что в данном случае order by a
эквивалентен order by b,a.
Да и в целом это способ не приемлим, т.к. запрос создаётся генератором и может сильно варьироваться.

Есть ещё один вариант: создать два индекса: по a и по b:
CREATE INDEX ON EVENTS IDX_A (A)
CREATE INDEX ON EVENTS IDX_B (B)

Тогда получаем план
PLAN (EVENTS ORDER IDX_A INDEX (IDX_A, IDX_B))

Строка INDEX (IDX_A, IDX_B) как я понимаю означает слияние битовых масок.
При этом выходной поток можно автоматически сделать отсортированным по IDX_A.


Тут стоит привести типичную кардинальность для таблицы
1) Общее количество записей ~1e7
2) Условие a>:a оставляет ~1e5
3) Условие b=:b оставляет ~1e3 (но индекс только по b недостаточно)

И вот что оказалось. Максимальную для данного запроса даёт план
PLAN SORT ((EVENTS INDEX (IDX_B))), который означает выборку по индексу
IDX_B, и сортировку для выхода. Очевидно что быстрее отсортировать небольшой массив в памяти чем сливать битовые маски.

Насколько же метод битовых масок маштабируется вверх? Если таблица имеет 1e8 записей? Сложно сказать, без чёткого понимания алгоритма.




Ответить