Удалить из пустой таблицы, принимая навсегда - PullRequest
5 голосов
/ 22 марта 2010

У меня есть пустая таблица, в которой ранее было большое количество строк.

Таблица содержит около 10 столбцов и индексов для многих из них, а также индексов для нескольких столбцов.

DELETE FROM item WHERE 1=1

Это займет приблизительно 40 секунд, чтобы завершить

SELECT * FROM item

это занимает 4 секунды.

План выполнения SELECT * FROM ITEM показывает следующее:

SQL> select * from midas_item;

no rows selected

Elapsed: 00:00:04.29

Execution Plan
----------------------------------------------------------
 0      SELECT STATEMENT Optimizer=CHOOSE (Cost=19 Card=123 Bytes=73
      80)

1    0   TABLE ACCESS (FULL) OF 'MIDAS_ITEM' (Cost=19 Card=123 Byte
      s=7380)





Statistics
----------------------------------------------------------
      0  recursive calls
      0  db block gets
   5263  consistent gets
   5252  physical reads
      0  redo size
   1030  bytes sent via SQL*Net to client
    372  bytes received via SQL*Net from client
      1  SQL*Net roundtrips to/from client
      0  sorts (memory)
      0  sorts (disk)
      0  rows processed

любая идея, почему это займет так много времени и как это исправить, будет принята с благодарностью !!

Ответы [ 5 ]

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

Одной из возможностей является блокировка. То есть в таблице была строка, которая была зафиксирована и заблокирована другим удалением. Ваше удаление сидел и ждал на замке. Когда транзакция блокировки была зафиксирована, ваше удаление могло быть завершено.

Вторая возможность заключается в том, что вы сначала запустили удаление, которое извлекло блоки с диска в кеш (что заняло время). Когда выбор выполнялся, данные находились в кеше и поэтому работали быстрее. Я думаю, что это менее вероятно, так как вы выбираете статистику, обозначенную «5252 физических чтений», поэтому она не получала их из кеша SGA. Вполне возможно, что кеш диска был задействован.

Третья возможность состоит в том, что есть триггер BEFORE / AFTER DELETE (не FOR EACH ROW), который что-то сделал.

Четвертая возможность состоит в том, что УДАЛЕНИЕ привело к отложенной очистке блока. Когда строки были фактически удалены, если они были записаны на диск до фиксации, у них все еще будет информация о блокировке / транзакции. Приходит ваше удаление, читает блоки, видит устаревшую информацию о транзакции, удаляет ее и перезаписывает блок.

Пятая возможность - это спор. Возможно, одновременно с удалением происходило больше событий.

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

3 голосов
/ 22 марта 2010

Если ваша таблица ранее была заполнена большим количеством данных, то Oracle отсканирует ее до максимальной отметки, даже если у нее нет данных СЕЙЧАС. Вы можете использовать оператор TRUNCATE для сброса HWM.

Также на AskTom

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

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

Очень длинное и полезное обсуждение можно найти на форуме Ask Tom. В зависимости от вашего бизнеса может быть, вы можете применить больше методов.

http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:2345591157689

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

Если у вас много индексов в таблице, тогда удаление займет некоторое время, потому что каждая запись в индексе также нуждается в удалении. Индексы ускоряют процессы чтения и замедляют запись или другие процессы модификации (отсюда и быстрый выбор).

- РЕДАКТИРОВАТЬ: Извините, не прочитал вопросы полностью. Если таблица пуста, это не может быть проблемой индекса. или я буду удивлен, если это было -

1 голос
/ 22 марта 2010

Если вы регулярно удаляете все строки из таблицы, «усеченная таблица XXX» обычно намного быстрее, чем массовое удаление. Может быть, попробуйте и посмотрите, насколько быстрее вы можете получить это.

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