простой запрос UPDATE для большой таблицы имеет плохую производительность - PullRequest
0 голосов
/ 27 февраля 2019

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

UPDATE table1
SET name = @name (this is the stored procedure inputparameter)
WHERE name IS NULL

В Table1 нет индексов или ключей, 5 столбцов, которые являются 4 целыми числами, и 1 varchar (обновляемый столбец 'name' это varcharстолбец)

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

Я использую Azure SQL DB Standard S6 (400DTU).

Может кто-нибудь дать мне совет по улучшению производительности?

Спасибо!

Ответы [ 4 ]

0 голосов
/ 27 февраля 2019

Нет.Вы обновляете 15 000 000 строк, что займет много времени.Каждое обновление имеет накладные расходы для поиска строки и регистрации значения.

При таком количестве обновляемых строк маловероятно, что накладные расходы находят строки.Если вы добавите индекс на name, обновление фактически должно будет обновлять индекс, а также обновлять исходные значения.

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

UPDATE TOP (100000) table1
    SET name = @name (this is the stored procedure inputparameter)
    WHERE name IS NULL;

100 000 строк должны составлять около 30 секунд или около того.

В этом случае индекс name делает Помогите.В противном случае каждая итерация цикла по сути будет читать всю таблицу.

0 голосов
/ 27 февраля 2019

Все, что вам нужно, это INDEX через

       Create INDEX I1 ON table1(P_key)

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

0 голосов
/ 27 февраля 2019

Вы можете сделать с помощью следующего метода?

UPDATE table1
SET name = ISNULL(name,@name)

для нулевых значений он будет обновляться с @name, а остальные будут обновляться с тем же значением.

0 голосов
/ 27 февраля 2019

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

1 - Создать новую таблицу, используя INTO (которая будет копировать данные), как в следующем запросе.

  SELECT 
       CASE 
              WHEN NAME IS NULL THEN @name 
              ELSE NAME 
       END AS NAME, 
       <other columns > 
INTO   dbo.newtable
FROM table1

2 - отбросить старую таблицу

drop table table1

3 - переименовать новую таблицу в table1

exec sp_rename 'dbo.newtable', 'table1'

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

WHILE EXISTS (SELECT 1 FROM table1 WHERE name is null)
BEGIN
    UPDATE TOP (10000) table1
    SET name = @name
    WHERE n ame is null
END
...