Создание индекса только для запроса в Oracle 10g - PullRequest
2 голосов
/ 05 января 2010

У меня около 3,5 миллионов записей в конкретной таблице в Oracle 10g, и я хочу запросить все записи с одним конкретным столбцом, имеющим значение NULL.

У меня вопрос: стоит ли создавать индекс для этого столбца только для этого одного запроса? Будет ли время, сэкономленное при использовании индекса, компенсировать время, затрачиваемое на его создание? Или мне просто сделать запрос без индекса?

Обратите внимание, что у меня нет возможности заранее создать индекс для меня, и если я создаю индекс только для запроса, я должен немедленно удалить его.

p / s: я искал существующие вопросы, но не могу найти ответ, который хочу. Укажите на любые подобные вопросы, которые я мог бы пропустить.

Ответы [ 4 ]

4 голосов
/ 05 января 2010

Создание индекса будет намного дороже, чем один запрос. Без индекса запрос будет просто сканировать таблицу. Построение индекса также должно сканировать таблицу, а затем построить и записать индекс.

2 голосов
/ 05 января 2010

Если я правильно помню, Oracle не индексирует значения NULL;таким образом, если все поля, которые входят в индекс, равны NULL, в этой строке не будет записи индекса.Так, например, если у вас есть таблица типа

ID      NUMBER PRIMARY KEY
FIELD1  NUMBER
FIELD2  NUMBER

с индексами

ID_INDEX (ID) PRIMARY KEY
FIELD1_INDEX (FIELD1)
FIELD2_INDEX (FIELD2)

и данными

ID=1  FIELD1=NULL  FIELD2=1
ID=2  FIELD1=2     FIELD2=NULL
ID=3  FIELD1=3     FIELD2=3
ID=4  FIELD1=NULL  FIELD2=NULL

, в ней должно быть четыре записиID_INDEX, но только два в FIELD1_INDEX и FIELD2_INDEX.В этом можно убедиться, запросив представление DBA_IND_STATISTICS (после сбора статистики таблицы):

SELECT * FROM DBA_IND_STATISTICS WHERE TABLE_NAME = 'whatever';

и просмотрев столбцы DISTINCT KEYS и NUM_ROWS.

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

Надеюсь, это поможет.

1 голос
/ 05 января 2010

Если у вас Enterprise Edition и у вас многопроцессорная система, вам следует рассмотреть возможность использования параллельного запроса. Это самый быстрый способ получения результата от полного сканирования таблицы, хотя он требует административных затрат и требует наличия нескольких процессоров (очевидно),

1 голос
/ 05 января 2010

Не могли бы вы разделить таблицу таким образом, чтобы значения NULL оказались в одном разделе? Если я не ошибаюсь (извините, не могу проверить это прямо сейчас), значения NULL отправляются в раздел MAXVALUE в многораздельной таблице диапазона. Я думаю, что Oracle прекрасно справится с удалением разделов и, следовательно, будет сканировать только раздел, содержащий значения NULL. Вам просто нужно выбрать подходящее число, которое будет высоким значением предыдущего раздела, чтобы исключить большинство или все нежелательные строки.

Пример (скажем, my_column - это число, и вы хотите найти NULL):

create table test_table (
  my_column number,
  other_columns ...
)
partition by range (my_column)
(
  partition not_null values less than (99999999999999),
  partition nulls    values less than (MAXVALUE)
);

Тогда, если вы "выберите * из test_table, где my_column равно нулю", план выполнения должен показывать только сканируемые "нулевые" разделы (полное сканирование, но оно будет содержать в основном только то, что вы хотите).

Не забудьте включить перемещение строк, если значение может быть изменено с нулевого на ненулевое и наоборот.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...