Индекс по столбцу только с двумя различными значениями - PullRequest
5 голосов
/ 23 марта 2010

Меня интересует производительность этого индекса:

У меня есть столбец "Invalid" varchar (1), который имеет 2 значения: NULL или 'Y' У меня есть индекс на (недействительный), а также (недействительный, last_validated) Last_validated - дата-время (используется для несвязанного запроса SELECT)

Я отмечаю небольшое количество элементов (1-5%) строк в таблице как «подлежащие удалению».
Это так, когда я

 DELETE FROM items WHERE invalid='Y'

не выполняет полное сканирование таблицы для недействительных элементов.

Похоже, проблема в том, что собственно DELETE теперь довольно медленный, возможно потому, что все индексы удаляются по мере их удаления.

Будет ли растровый индекс обеспечивать лучшую производительность для этого? или, может быть, нет индекса вообще?

Ответы [ 5 ]

2 голосов
/ 23 марта 2010

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

Дополнительные соображения:

  • существуют ли неиндексированные ссылки внешнего ключа на эту таблицу из других таблиц?
  • есть ли в этой таблице триггеры, выполняющие другой DML?
1 голос
/ 23 марта 2010

Индекс должен использоваться, но DELETE все еще может занять некоторое время.

Посмотрите на план выполнения DELETE:

EXPLAIN PLAN FOR
  DELETE FROM items WHERE invalid='Y';

SELECT * FROM TABLE( dbms_xplan.display );

Вы можете попробовать использовать Bitmap Index, но я сомневаюсь, что это сильно повлияет на производительность.


Использование NULL в качестве значения не очень хорошая идея. Запрос

SELECT something FROM items WHERE invalid IS NULL

не сможет использовать ваш индекс, поскольку он содержит только ненулевые значения.

0 голосов
/ 24 марта 2010

Рекомендую:

  1. проверьте, сколько записей вы ожидаете, что DELETE повлияет (т. Е. Может быть, больше, чем вы ожидаете)
  2. если количество строк, которые должны быть удалены, относительно мало, убедитесь, что индекс на invalid действительно используется DELETE
  3. получить трассировку в сеансе, чтобы увидеть, что он делает - возможно, он читает больше блоков с диска, чем ожидалось, или может ожидать (например, блокировка записи или конфликт защелки)

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

0 голосов
/ 24 марта 2010

Удалите индекс (недействительно) и попробуйте и SELECT, и DELETE. У вас уже есть индекс (недействительный, last_validated). Вы не должны нуждаться в индексе для одного недопустимого. Также приблизительно, сколько строк в этой таблице?

0 голосов
/ 23 марта 2010

Две мысли об этом ...

  1. Использование NULL для выражения противоположности 'Y', возможно, не очень хорошая идея. Null означает * Я не знаю, что это за значение 'или' нет никакого значимого ответа вопрос'. Вы должны действительно использовать «N» как противоположность «Y». Это устранит проблему поиска допустимых элементов, поскольку Oracle не будет использовать индекс для этого столбца, если он содержит только ненулевые значения.

  2. Возможно, вы захотите добавить CHECK CONSTRAINT в такой столбец, чтобы обеспечить ввод только допустимых значений.

Однако ни одно из этих изменений не обязательно влияет на производительность DELETE.

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