Почему «удаление из таблицы» занимает много времени, когда «усечение таблицы» занимает 0 раз? - PullRequest
16 голосов
/ 24 декабря 2008

(я пробовал это в MySql)

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

Ответы [ 6 ]

30 голосов
/ 24 декабря 2008

усеченную таблицу нельзя откатить, это все равно что сбросить и воссоздать таблицу.

23 голосов
/ 24 декабря 2008

... просто чтобы добавить некоторые детали.

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

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

8 голосов
/ 24 декабря 2008

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

Truncate эффективно удаляет таблицу и воссоздает ее, и ее нельзя выполнить в транзакции. Поэтому требуется меньше операций и выполняется быстро. Truncate также не использует никаких триггеров на удаление.

Точную информацию о том, почему это быстрее в MySql, можно найти в документации MySql: http://dev.mysql.com/doc/refman/5.0/en/truncate-table.html

6 голосов
/ 25 декабря 2008

Ваш вопрос был о MySQL, и я почти ничего не знаю о MySQL как о продукте, но я подумал, что добавлю, что в SQL Server оператор TRUNCATE может откатываться. Попробуйте сами

create table test1 (col1 int)
go
insert test1 values(3)
begin tran
truncate table test1
select * from test1
rollback tran
select * from test1

В SQL Server TRUNCATE регистрируется, он просто не регистрируется таким многословным способом, как DELETE. Я считаю, что это называется минимально зарегистрированной операцией. Фактически страницы данных все еще содержат данные, но их экстенты были помечены для удаления. Пока страницы данных все еще существуют, вы можете откатить усечение. Надеюсь, это полезно. Мне было бы интересно узнать результаты, если кто-то попробует это на MySQL.

1 голос
/ 25 сентября 2009

Для MySql 5, использующего InnoDb в качестве механизма хранения, TRUNCATE действует так же, как DELETE, без предложения WHERE: то есть для больших таблиц это занимает много времени, потому что он удаляет строки одну за другой. Это меняется в версии 6.x.

см.

http://dev.mysql.com/doc/refman/5.1/en/truncate-table.html

для информации 5.1 (строка за строкой с InnoDB) и

http://blogs.mysql.com/peterg/category/personal-opinion/

для изменений в 6.x


Примечание редактора

Этот ответ явно противоречит документации MySQL :

"Для таблицы InnoDB до версии 5.0.3 InnoDB обрабатывает TRUNCATE TABLE, удаляя строки одну за другой. Начиная с MySQL 5.0.3, удаление строка за строкой используется, только если есть какие-либо ограничения FOREIGN KEY, которые ссылаются на таблицу . Если ограничений FOREIGN KEY нет, InnoDB выполняет быстрое усечение, удаляя исходную таблицу и создавая пустую таблицу с таким же определением, что намного быстрее, чем удаление строк одна за другой. "

0 голосов
/ 14 августа 2013

Усечение находится на уровне таблицы, а удаление - на уровне строки. Если бы вы перевели это в sql в другом синтаксисе, усечение было бы:

DELETE * FROM table

удаляя все строки одновременно, а оператор DELETE (в PHPMyAdmin) выглядит так:

DELETE * FROM table WHERE id = 1
DELETE * FROM table WHERE id = 2

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

...