2010-03-23 2 views
5

Я задаюсь о выполнении этого показателя:индекс столбца только с 2 различными значениями

У меня есть «Invalid» VARCHAR (1) столбец, который имеет 2 значения: NULL или «Y» У меня есть index on (недействительный), а также (недействительный, last_validated) Last_validated - это datetime (это используется для несвязанного запроса SELECT)

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

DELETE FROM items WHERE invalid='Y' 

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

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

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

ответ

0

Две мысли по этому поводу ...

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

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

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

+2

Логично, я согласен с вашей точкой # 1; на практике, однако, есть * в некоторых случаях * значительные преимущества в производительности для представления неинтересных значений как NULL в столбце из-за того, что Oracle не хранит все нулевые строки в индексах - если запросы в этом столбце почти всегда интересуются в редких значениях «Y», то наличие non-'Y', представленное как NULL, может иметь огромное влияние на производительность запросов, обновлений и удалений. –

+0

[Эта статья] (https://richardfoote.wordpress.com/2011/08/10/indexing-a-column-with-just-one-distinct-value-all-the-madmen/) более подробно подтверждает @ Заявление ДжеффриКемпа. – GolezTrol

1

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

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

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

SELECT * FROM TABLE(dbms_xplan.display); 

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


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

SELECT something FROM items WHERE invalid IS NULL 

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

2

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

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

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

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

+0

Преимущество индекса на 'invalid' заключается в том, что оно будет содержать только строки, где' invalid' не равно null, и поэтому будет очень быстро запрашивать. С другой стороны, '(invalid, last_validated)' будет содержать запись для каждой строки, которая имеет либо непустой 'invalid', либо' last_validated'; если 'last_validated' в основном не равен нулю, индекс будет довольно большим и, следовательно, менее подходит для этой операции DELETE. –

0

Я рекомендую:

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

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

Смежные вопросы