Обновление столбца Varchar таблицы, содержащей> 10 миллионов строк - PullRequest
0 голосов
/ 02 марта 2012

В последнее время мы сталкиваемся с серьезными проблемами производительности в наших заявлениях Update, раньше обновление занимало 3 минуты, а теперь обновление занимает почти 2 часа.В соответствии с последним дизайном БД мы изменили код хранимой процедуры, как показано ниже.

Вот мой сценарий подробно: у меня очень большая таблица фактов с более чем 10 миллионами строк, и мне нужно обновить столбец этой таблицы фактов, когда условие выполнено.Итак, мы написали инструкцию update для обновления этого столбца:

declare @var  varchar(max) = (select metrcikey from metricdim where metrciname ='XYZ')

Update 
    fopty
set 
    Metrickey = metrickey+','+@var 
from 
    optyfact opty 
inner join  
    optydim dim on opty.optyid = dim.optyid
inner join 
    geodim geo on geo.atukey = opty.atukey 
inner join 
    agreementdim ag on opty.optyid = ag.optyid 
inner join 
    account acc on acc.optyid = acc.optyid 
where 
    dim.optytype= 'ABC'
    and geo.atukey =145
    and ag.agreementtype ='Sold'
    and acc.accountteamManager  ='XXX'

Есть ли способ оптимизировать вышеуказанный запрос, согласно моему пониманию, оператор, выполняющий запрос в течение 2 часов, из-за SETоператор

Metrickey = Metrickey + @var

здесь Metrickey столбец равен varchar, а переменная @var также varchar(max), для объединения этой строки требуется больше времени.

Это будетМне очень поможет, если приведенный выше запрос может быть оптимизирован, поэтому, пожалуйста, предложите лучший способ обновить столбец varchar значением varchar.

Ответы [ 2 ]

0 голосов
/ 04 марта 2012

Вы должны рассмотреть возможность обновления этого в пакетах (скажем, 100 000 строк за один раз), вместо того, чтобы пытаться обновить все строки в одном кадре. Это не обязательно займет меньше времени в целом, но не заблокирует все на два часа. Мы можем записать фактические значения optyid во временную таблицу, чтобы нам не приходилось постоянно ссылаться на базовые таблицы в обновлении.

CREATE TABLE #q(rn INT IDENTITY(1,1) PRIMARY KEY, optyid INT);

DECLARE 
  @rc    INT, 
  @step  INT = 1,
  @chunk INT = 100000; 

INSERT #q(optyid) SELECT DISTINCT opty.optyid
FROM dbo.optyfact AS opty 
INNER JOIN dbo.optydim AS dim      ON opty.optyid = dim.optyid
INNER JOIN dbo.geodim AS geo       ON geo.atukey = opty.atukey 
INNER JOIN dbo.agreementdim AS ag  ON opty.optyid = ag.optyid 
INNER JOIN dbo.account AS acc      ON acc.optyid = acc.optyid 
WHERE 
  dim.optytype = 'ABC';
  AND geo.atukey = 145
  AND ag.agreementtype = 'Sold'
  AND acc.accountteamManager = 'XXX';

SET @rc = @@ROWCOUNT;

WHILE @step <= ((@rc / @chunk) + 1)
BEGIN
    BEGIN TRANSACTION;

    UPDATE o SET MetricKey += ',' + @var
    FROM dbo.optyfact AS o
    INNER JOIN #q AS q ON o.optyid = q.optyid
    WHERE q.rn BETWEEN (((@step-1)*@chunk)+1) AND (@step*@chunk);

    COMMIT TRANSACTION;
    CHECKPOINT;
    SET @step += 1;
END

DROP TABLE #q;
0 голосов
/ 03 марта 2012

Реального секретного сверхбыстрого решения для обновления столбца VARCHAR не существует. Это будет относительно медленно, несмотря ни на что, но есть вещи, которые вы можете сделать, чтобы уменьшить боль.

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

ПРИМЕЧАНИЕ. Я предполагаю, что в вашем коде есть опечатка - «Обновить fopty» должно читаться как «Обновить opty», правильно?

В случае таблицы optyfact (opty alias) у вас должен быть индекс для столбцов optyid и atukey, который включает metrickey.

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

Как только вы все это настроите, пройдите анализатор запросов, чтобы убедиться, что вы выполняете INDEX SEEKs для всех таблиц, в противном случае он будет работать в течение ДЛИТЕЛЬНОГО времени, как вы указали.

Кроме того, убедитесь, что вы объединяетесь в узких колоннах. INT хорошие, VARCHAR плохие.

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

Это все, что я получил. Удачи!

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