Индекс для обнуляемого столбца - PullRequest
7 голосов
/ 07 февраля 2012

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

SELECT e.ename 
FROM   emp e;

В плане объяснения я вижу FULL TABLE SCAN (даже подсказка не помогла)

SELECT e.ename 
FROM   emp e
WHERE  e.ename = 'gdoron';

Использует ли индекс ...

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

Мой вопрос прост: почему в индексах нет нулевых записей?

Ответы [ 3 ]

17 голосов
/ 07 февраля 2012

По умолчанию реляционные базы данных игнорируют значения NULL (потому что реляционная модель говорит, что NULL означает «не присутствует»). Таким образом, Index не хранит значение NULL, следовательно, если в операторе SQL указано нулевое условие, связанный индекс игнорируется (по умолчанию).

Но вы можете решить эту проблему, отметив статью ЭТОГО или ЭТОГО .

3 голосов
/ 07 февраля 2012

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


@A.B.Cade: вполне возможно, что оптимизатор решит использовать индекс, но маловероятно. Допустим, у вас есть таблица с индексированной таблицей с 100 строками, но только с 10 значениями. Если оптимизатор использует индекс, он должен получить 10 строк из индекса, а затем расширить его до 100 строк, тогда как при сканировании полной таблицы он получает все 100 строк с самого начала. Вот пример:

create table test1 (blarg varchar2(10));

create index ak_test1 on test1 (blarg);

insert into test1
select floor(level/10) from dual connect by level<=100;

exec dbms_stats.gather_table_stats('testschema','test1');

exec dbms_stats.gather_index_stats('testschema','ak_test1');

EXPLAIN PLAN FOR
select * from test1;

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

0 голосов
/ 07 февраля 2012

Я не уверен, что первый запрос уместен с точки зрения использования индекса, по крайней мере, второй мог бы.

В любом случае, хотя вы не можете индексировать столбец, содержащий нулевое значение, есть способы сделать это, например:

create index MY_INDEX on emp(ename, 1);

обратите внимание на , 1) в конце, который делает трюк.

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