Какой индекс следует создать для столбцов с низкой кардинальностью и высоким обновлением в оракуле?

В Oracle 11g, скажем, у меня есть таблица Task, в которой есть столбец ProcessState. Значения этого столбца могут быть Queued, Running и Complete (в будущем может быть еще несколько состояний). В таблице будет более 50 миллионов данных, причем 99,9% строк имеют Complete в качестве значения столбца. Только несколько тысяч строк будут иметь значение Queued/Running.

Я читал, что, хотя индекс bitmap хорош для столбца с низкой кардинальностью, он в основном используется для статических таблиц.

Итак, какой индекс может улучшить запрос для Queued/Running задач? bitmap или обычный неуникальный b-tree индекс?

Кроме того, какой индекс может улучшить запрос для двоичного столбца (NUMBER(1,0) только со значениями yes/no)?

Отказ от ответственности: я случайный dba.


person mshsayem    schedule 22.02.2016    source источник
comment
В вашем случае растровый индекс предпочтительнее. Вы сказали... 99,9% строк, имеющих Complete... в случае, если вы ОБНОВЛЯЕТЕ Task.ProcessState только из одного сеанса, вы не повлияете на производительность, иначе сеансы должны будут сериализовать свой доступ к индексу.   -  person Sergiu Velescu    schedule 22.02.2016
comment
Какой запрос вы пытаетесь улучшить?   -  person a_horse_with_no_name    schedule 22.02.2016
comment
@a_horse_with_no_name Вот так: select task_id from task where processstate=0 (ожидается только ‹ 500 строк).   -  person mshsayem    schedule 22.02.2016


Ответы (2)


Я предполагаю, что вы заинтересованы в выборе строк с состояниями (в очереди/выполняется) для их обновления. Так что было бы неплохо отделить завершенные строки от остальных, потому что нет особого смысла индексировать завершенные строки. Здесь можно использовать разделение или индекс на основе функций, когда функция возвращает NULL для завершенных строк и фактические значения для остальных, в этом случае в дереве индекса отображаются только незавершенные строки.

person Ilia Maskov    schedule 22.02.2016

Обычный индекс (b*tree) подойдет. Просто убедитесь, что в столбце есть гистограмма. (См. параметр METHOD_OPT в DBMS_STATS.GATHER_TABLE_STATS).

Имея гистограмму в этом столбце, Oracle будет иметь данные, необходимые для того, чтобы убедиться, что он использует индекс при поиске поставленных в очередь/выполняемых заданий, но использует полное сканирование таблицы при поиске завершенного задания.

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

Кроме того, какой индекс может улучшить запрос для двоичного столбца (ЧИСЛО (1,0) только со значениями да/нет)

Извините, я пропустил эту часть вашего вопроса. Если данные в столбце искажены (т. е. почти все 1 или почти все 0), то используется обычный (b*tree) индекс, как указано выше. Если данные распределены равномерно, то никакой индекс не поможет. Чтение 50% строк вашей таблицы через индекс будет медленнее, чем полное сканирование таблицы.

person Matthew McPeak    schedule 23.02.2016
comment
Обычный индекс (B-дерево) — это хорошо, но неэффективно включать в индекс растущие строки с полным состоянием. В общем случае единственным подходящим методом для увеличения набора полных записей состояния является FTS. Таким образом, мы получаем накладные расходы на обслуживание индекса без какой-либо выгоды. Так что, ИМХО, неплохо индексировать только неполные строки состояния. - person Ilia Maskov; 24.02.2016
comment
Я старался, чтобы мой ответ был простым; используя предоставленную информацию. Мне кажется, что OP был назначен ролью администратора баз данных и пытается улучшить производительность существующего приложения. Индексы на основе функций можно использовать для пропуска завершенных записей, но тогда вам придется изменить запросы приложения, чтобы использовать ту же функцию, иначе вы не получите никакой выгоды. Я не предполагал, что у него есть время, полномочия и т. д., чтобы внести такие изменения. С таблицей, которую он описал, и целями запроса, которые он дал, индекс b*tree для ProcessState будет быстрым и эффективным решением, даже если он действительно занимает некоторое пространство. - person Matthew McPeak; 24.02.2016