Мой вопрос касается Oracle 11g и использования индексов в запросах SQL.
В моей базе данных есть таблица, которая имеет следующую структуру:
Table tab (
rowid NUMBER(11),
unique_id_string VARCHAR2(2000),
year NUMBER(4),
dynamic_col_1 NUMBER(11),
dynamic_col_1_text NVARCHAR2(2000)
) TABLESPACE tabspace_data;
Я создал дваиндексы:
CREATE INDEX Index_dyn_col1 ON tab (dynamic_col_1, dynamic_col_1_text) TABLESPACE tabspace_index;
CREATE INDEX Index_unique_id_year ON tab (unique_id_string, year) TABLESPACE tabspace_index;
Таблица содержит от 1 до 2 миллионов записей.Я извлекаю из него данные, выполняя следующую команду SQL:
SELECT distinct
"sub_select"."dynamic_col_1" "AS_dynamic_col_1","sub_select"."dynamic_col_1_text" "AS_dynamic_col_1_text"
FROM
(
SELECT "tab".* FROM "tab"
where "tab".year = 2011
) "sub_select"
К сожалению, для выполнения запроса требуется около 1 часа, хотя я создал оба индекса, описанных выше.План объяснения показывает, что Oracle использует «Таблицу полного доступа», то есть полное сканирование таблицы.Почему индекс не используется?
В качестве эксперимента я протестировал следующую команду SQL:
SELECT DISTINCT
"dynamic_col_1" "AS_dynamic_col_1", "dynamic_col_1_text" "AS_dynamic_col_1_text"
FROM "tab"
Даже в этом случае индекс не используется и выполняется полное сканирование таблицы..
В моей реальной базе данных таблица содержит больше индексированных столбцов, таких как «dynamic_col_1» и «dynamic_col_1_text».Весь индексный файл имеет размер около 50 ГБ.
Несколько дополнительных сведений:
- База данных - Oracle 11g, установленная на моем локальном компьютере.
- Iиспользуйте Windows 7 Enterprise 64bit.
- Весь индекс разделен на 3 dbf-файла размером около 50 ГБ.используйте индекс в первом запросе.Поскольку первый запрос используется другой программой для извлечения данных из базы данных, его вряд ли можно изменить.Поэтому было бы неплохо настроить таблицу вместо этого.
Заранее спасибо.
[01.10.2011: ОБНОВЛЕНИЕ]
Я думаю, что нашел решение дляпроблема.Оба столбца dynamic_col_1
и dynamic_col_1_text
могут иметь значение NULL.После изменения таблицы, запрещающей значения NULL в обоих столбцах, и добавления нового индекса исключительно для столбца year
, Oracle выполняет быстрое сканирование индекса.Преимущество состоит в том, что теперь выполнение запроса занимает около 5 секунд, а не 1 час, как раньше.