Удалите большой объем данных в SQL-сервере

Предположим, что у меня есть таблица с 10 000 000 записей. Что такое различие между этими двумя решениями?

  1. удалите данные как:

    DELETE FROM MyTable
    
  2. удалите все данные со строкой приложения строкой:

    DELETE FROM MyTable WHERE ID = @SelectedID
    

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

8
задан Brian Tompsett - 汤莱恩 6 July 2015 в 11:26
поделиться

6 ответов

Если у вас есть много записей в вашем столе, и вы хотите удалить их все, вы должны рассмотреть Trunchate

вместо Удалить из
. Это будет намного быстрее, но осознавать, что он не может активировать триггер.

См. Подробнее (этот случай SQL Server 2000): http://msdn.microsoft.com/en-us/library/aa260621%28sql.80%29.aspx

Удаление таблицы в приложении ряд по ряду в конечном итоге Долго долгое время, поскольку ваша СУБД не может ничего оптимизировать, так как он заранее не знает, что вы собираетесь удалить все.

14
ответ дан 5 December 2019 в 04:42
поделиться

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

DECLARE @RowsDeleted INTEGER
SET @RowsDeleted = 1

WHILE (@RowsDeleted > 0)
    BEGIN
        -- delete 10,000 rows a time
        DELETE TOP (10000) FROM MyTable [WHERE .....] -- WHERE is optional
        SET @RowsDeleted = @@ROWCOUNT
    END

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

Если вы используете SQL 2000 или ранее, верхнее состояние недоступно, поэтому вместо этого вы можете использовать Set Rowcount.

DECLARE @RowsDeleted INTEGER
SET @RowsDeleted = 1
SET ROWCOUNT 10000 -- delete 10,000 rows a time

WHILE (@RowsDeleted > 0)
    BEGIN
        DELETE FROM MyTable [WHERE .....] -- WHERE is optional
        SET @RowsDeleted = @@ROWCOUNT
    END
21
ответ дан 5 December 2019 в 04:42
поделиться

Первый имеет явно лучшую производительность.

Когда вы указываете удаление [MyTable], он просто стесняет все, не выполняя проверку ID. Второй будет тратить время и дисковые работы, чтобы найти соответствующую запись каждый раз, прежде чем удалять его.

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

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

3
ответ дан 5 December 2019 в 04:42
поделиться

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

Если вы хотите избавиться от всех данных, Trunchate Table MyTable будет быстрее, чем оба, хотя у него нет объекта Чтобы фильтровать строки, он делает изменение метаданных на задней панели и в основном падает IAM на полу для рассматриваемой таблицы.

3
ответ дан 5 December 2019 в 04:42
поделиться

Лучшие характеристики для очистки таблицы приведут Trunchate Table MyTable . См. http://msdn.microsoft.com/en-us/library/ms177570.aspx для более подробных объяснений

2
ответ дан 5 December 2019 в 04:42
поделиться

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

Теперь, если вы должны удалить все данные из таблицы, и вы не полагаетесь на откат, подумайте об использовании Trunchate Table

0
ответ дан 5 December 2019 в 04:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: