2013-12-10 2 views
0

У меня огромный стол (200 миллионов записей). около 70% не нужны сейчас (в таблице есть столбец ACTIVE, и эти записи имеют значение N). Существует много индексов с несколькими столбцами, но ни один из них не содержит этот столбец. Будет ли удаление 70% записей улучшать производительность SELECT (ACTIVE = 'Y') (потому что oracle должен читать табличные блоки без активных записей, а затем исключать их из конечного результата)? Требуется ли усадка?Удаление строк улучшит выбор производительности в oracle?

ответ

3

Это действительно невозможно сказать, не зная больше о ваших запросах.

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

С другой стороны, если вы выбираете почти все активные записи, то полное сканирование таблицы с 70% удаленных строк (и сокращение таблицы) займет всего 30% времени предварительного удаления.

Существует много других соображений - выбор набора данных и доступ к таблице через индексы и необходимость отклонения 99% строк после чтения таблицы, поскольку получается, что существует положительная корреляция между требуемыми строками и неактивный статус.

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

Если вам действительно не нужны эти неактивные записи, почему вы просто не удаляете их, а не отмечаете их неактивными?

Редактировать: Кроме того, хотя индексирование столбца с разделением 70/30 обычно не полезно, вы можете попробовать несколько других указательных трюков.

Например, если у вас есть индексированный столбец, который часто используется в запросах (client_id?), Вы можете добавить активный флаг к этому индексу. Кроме того, можно построить частичный индекс:

create index my_table_active_clients 
on my_table (case when active = 'Y' then client_id end); 

... и затем запрос на:

select ... 
from ... 
where (case when active = 'Y' then client_id end) = :client_id 

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

Другое редактирование: полезным побочным эффектом разделения может быть то, что он сохраняет неактивные записи и активные записи «физически» отдельно, и каждый блок, который считывается в память из «активного» раздела, конечно, имеет только активные записи. Это может привести к повышению эффективности кеша.

+0

Собственно, в этой таблице есть записи для каждого клиента. Есть индекс в столбце CLIENT_ID, который используется в моем запросе. Но в запросе у меня также есть условие ACTIVE = Y (таблица содержит около 70% активных записей, а мой индекс не создается в столбце ACTIVE). Поэтому я думаю, что мы говорим о третьем варианте «Есть много других соображений». Правильно ли мой подход? Ежедневное удаление этих строк улучшит мой запрос? – user3032111

+0

Возможно, наиболее справедливо сказать, что будут затронуты некоторые запросы, а некоторые - нет. –

+0

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

1

Да, это скорее всего. Но в зависимости от вашей схемы доступа увеличение, скорее всего, будет не таким большим. Установка индекса, включая столбец, будет лучшим решением для будущего IMHO.

+1

И собрать статистику с гистограммами в этой колонке –

+0

Yepp. Но это очень просто:) – frlan

+0

Хорошо, но если я удаляю записи с ACTIVE = N каждый день (например, используя задание) и не создаю индекс в активном столбце, будет ли это нормально? – user3032111

2

Разделение, размещение активных = «НЕТ» записей в отдельном разделе, может быть хорошим вариантом. http://docs.oracle.com/cd/B19306_01/server.102/b14223/parpart.htm

+0

Я это рассмотрю. Включение ROW MOVEMENT потребует удаления и вставки данных в случае обновления флага ACTIVE, да? – user3032111

+0

Не совсем, обновление ключа разбиения приведет к перемещению записи в другое физическое местоположение (раздел). Да, на DML будут некоторые накладные расходы. –

0

Скорее всего нет. Удалить не уменьшит размер сегмента таблицы. Может потребоваться дополнительное обслуживание.После DELETE выполнить также:

ALTER TABLE <tablename> SHRINK SPACE COMPACT; 
ALTER INDEX <indexname> SHRINK SPACE COMPACT; -- for every table's index 

В качестве альтернативы вы можете использовать старый школьный подход:

ALTER TABLE <tablename> MOVE; 
ALTER INDEX <indexnamename> REBUILD; 

Когда delting 70% таблицы также рассмотреть возможные решения CTAS (создать таблицу выбора). Это будет намного быстрее.

0

Индексирование играет важную роль в запросе SELECT. Производительность резко увеличится , если вы используете эти индексированные столбцы в запросе. Ya удаление строк повысит производительность наверняка несколько, но не резко.

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