Медленное обновление значений в таблице на основе другой таблицы - PullRequest
1 голос
/ 09 ноября 2010

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

select customers.name, countries.country
from customers
inner join countries on customers.countrycode = countries.countrycode

Однако написанное мной заявление об обновлении (которое, я уверен, это то же самое) занимает на несколько порядков большедля завершения.

update customers
set customers.country = countries.country
from customers
inner join countries on customers.countrycode = countries.countrycode

Есть предложения?

ОБНОВЛЕНИЕ:

Ниже приведен план инструкции SELECT

  |--Hash Match(Inner Join, HASH:([countries].[countrycode])=([Testing].[dbo].[customers].[countrycode]), RESIDUAL:(@countries.[countrycode] as [countries].[countrycode]=[Testing].[dbo].[customers].[countrycode]))
       |--Table Scan(OBJECT:(@countries AS [countries]))
       |--Table Scan(OBJECT:([Testing].[dbo].[customers]))  

Ниже приведен пландля оператора UPDATE

  |--Table Update(OBJECT:([Testing].[dbo].[Customers]), SET:([Testing].[dbo].[Customers].[Country] = @countries.[country] as [countries].[country]))
       |--Top(ROWCOUNT est 0)
            |--Stream Aggregate(GROUP BY:([Bmk1000]) DEFINE:([countries].[country]=ANY(@countries.[country] as [countries].[country])))
                 |--Nested Loops(Inner Join, WHERE:(@countries.[countrycode] as [countries].[countrycode]=[Testing].[dbo].[Customers].[countrycode]))
                      |--Table Scan(OBJECT:([Testing].[dbo].[Customers]))
                      |--Table Scan(OBJECT:(@countries AS [countries]))

Ответы [ 3 ]

3 голосов
/ 09 ноября 2010

Сначала UPDATE меняет таблицу. Это означает значительный I/O в журнале транзакций и в самих файлах данных, если во время обновления возникает контрольная точка.

Операция DML не быстрее, чем запрос.

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

Обновление:

Из вашего плана я вижу, что ключ UNIQUE не определен для countries.countrycode.

SQL Server должен найти одно значение для каждого countrycode, которое нужно присвоить customers (даже если есть одно значение на самом деле), и делает Stream Aggregate для этого.

Создать PRIMARY KEY на countries.countrycode.

1 голос
/ 09 ноября 2010

Индексы

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

0 голосов
/ 09 ноября 2010

Выберите имеет (если данные еще не находятся в памяти) ввода-вывода с диска.

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

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

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