Плюсы и минусы TRUNCATE против DELETE FROM - PullRequest
60 голосов
/ 15 июля 2010

Может ли кто-нибудь дать мне краткий обзор плюсов и минусов использования следующих двух утверждений:

TRUNCATE TABLE dbo.MyTable

против

DELETE FROM dbo.MyTable

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

Ответы [ 11 ]

83 голосов
/ 15 июля 2010

TRUNCATE не генерирует никаких данных отката, что делает его молниеносным.Он просто освобождает страницы данных, используемые таблицей.

Однако, если вы находитесь в транзакции и хотите иметь возможность «отменить» это удаление, вам нужно использовать DELETE FROM, что дает возможность отката.

РЕДАКТИРОВАТЬ: Обратите внимание, что вышеприведенное неверно для SQL Server (но это относится к Oracle).В SQL Server можно выполнить откат операции усечения, если вы находитесь внутри транзакции, и транзакция не была зафиксирована.С точки зрения SQL Server, одно ключевое отличие между DELETE FROM и TRUNCATE: this : "Оператор DELETE удаляет строки по одной за раз и записывает запись в журнале транзакций для каждой удаленной строки. TRUNCATE TABLE удаляетданные путем освобождения страниц данных, используемых для хранения данных таблицы, и записывают только освобождения страниц в журнале транзакций. "

Другими словами, во время TRUNCATE меньше регистрируется, потому что в освобождении записываются только освобождения страниц.журнал транзакций, в то время как с DELETE FROM удаление каждой строки записывается.Это одна из причин, по которой TRUNCATE работает молниеносно.

Обратите внимание, что по этой ссылке MSDN нельзя усекать таблицы, на которые ссылаются ограничения внешнего ключа, участвовать в индексированном представлении или опубликованы с использованием репликации транзакций или слияниярепликация.

РЕДАКТИРОВАТЬ 2: Другой ключевой момент заключается в том, что TRUNCATE TABLE сбрасывает вашу идентификацию в начальное начальное значение, тогда как DELETE FROM будет продолжать увеличиваться с того места, где оно было остановлено.Ссылка: ответ Бена Робинсона.

46 голосов
/ 15 июля 2010

Другим ключевым моментом, не упомянутым в других ответах, является то, что TRUNCATE TABLE будет сбрасывать вашу идентичность с начальным семенем , тогда как DELETE FROM будет увеличиваться с того места, где оно оставлено выкл.

8 голосов
/ 03 июля 2013

Другое отличие с точки зрения безопасности состоит в том, что TRUNCATE требует привилегий ALTER для таблицы, в то время как DELETE просто требует (барабанная дробь) разрешений DELETE для этой таблицы.

4 голосов
/ 15 июля 2010

TRUNCATE TABLE не регистрирует транзакцию. Это означает, что это молниеносно для больших столов. Недостатком является то, что вы не можете отменить операцию.

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

3 голосов
/ 07 сентября 2017

Схема удаления по сравнению с усечением в SQL-сервере

Для полной статьи примите после этого подключения: Удалить Vs Truncate в SQL Server

enter image description here

/*Truncate - Syntax*/
TRUNCATE TABLE table_name

/*Delete - Syntax*/
DELETE FROM table_name
WHERE some_condition
2 голосов
/ 24 апреля 2013

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

1 голос
/ 29 июня 2011

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

0 голосов
/ 11 августа 2018

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

0 голосов
/ 10 августа 2017

Другим отличием DELETE от TRUNCATE является поведение, когда таблица повреждена.

Например:

DELETE FROM table_name;

В результате возникнет ошибка:

Сообщение 3314, уровень 21, состояние 3, строка 1

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

Сообщение 0, уровень 20, состояние 0, строка 0

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

Пока TRUNCATE будет работать:

TRUNCATE TABLE table_name;
-- Command(s) completed successfully.
0 голосов
/ 26 мая 2017

Одна вещь, которая очень важна (imo) и не упоминается в других ответах, состоит в том, что TRUNCATE нужна блокировка стабильности схемы, Sch-S, тогда как DELETE использует блокировки строк.Давайте проверим следующее:

BEGIN TRANSACTION;

BEGIN TRY
    -- Truncate below will take LCK_M_SCH_S lock for TABLE_A
    TRUNCATE TABLE TABLE_A

    -- Lets say the query below takes 5 hours to execute
    INSERT INTO
        TABLE_A
    SELECT
        *
    FROM
        GIANT_TABLE (NOLOCK)
END TRY
BEGIN CATCH
    IF @@TRANCOUNT > 0
        ROLLBACK TRANSACTION;
    THROW
END CATCH

IF @@TRANCOUNT > 0
    COMMIT TRANSACTION;

Теперь предположим, что через 1-2 минуты после запуска этого запроса, скажем, мы попытались выполнить следующее:

SELECT COUNT(*) FROM TABLE_A (NOLOCK)

Обратите внимание, что япункт NOLOCK.Как вы думаете, что произойдет сейчас?Этот запрос будет ждать 5 часов.Зачем?Потому что для условия NOLOCK требуется Sch-S блокировка для TABLE_A, но для этого предложения TRUNCATE уже есть Sch-S.Поскольку мы еще не зафиксировали транзакцию, блокировка остается включенной даже после этого условия TRUNCATE.Sch-S блокировка таблицы в основном означает, что либо TABLE_A изменяется путем добавления / удаления столбцов и т. Д., Либо он усекается.Вы даже не можете выполнить что-то, как показано ниже:

SELECT object_id('TABLE_A')

Это будет зависать и 5 часов.Однако, если вы замените TRUNCATE на DELETE FROM, вы увидите, что в таблице не будет блокировки Sch-S, и приведенные выше запросы не будут зависать.

...