powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Обновление нескольких полей у большого числа строк
32 сообщений из 32, показаны все 2 страниц
Обновление нескольких полей у большого числа строк
    #39697974
gepard1980
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Есть база данных MS SQL Server 2008 R2 с нагрузкой 2000 транзакций в секунду. Есть таблицы lion_Tasks(uid_obj, order_new, __usn_field_order_new, и еще 40 полей) и таблица lion_Tasks_Changes_Parts(uid_task_cp, uid_user_cp, __usn_entity_cp и еще 20 полей ). На веб-сервер прилетает 10 тысяч объектов, у которых изменилось только одно поле order_new. В базе нужно обновить только 3 поля. Эти объекты передаю табличным параметром в хранимую процедуру:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
CREATE PROCEDURE dbo.lion_UpdateTasksNewOrder(  @Table TasksNewOrderTableType READONLY )
AS

BEGIN
	  	
    SELECT * INTO #t3 FROM @Table

    CREATE NONCLUSTERED INDEX IDX_T3_UID_TASK ON #t3(UUID_TASK)
    CREATE NONCLUSTERED INDEX IDX_T3_UID_USER ON #t3(UUID_USER)
      	      	        	        			
    UPDATE dbo.lion_Tasks
    SET     

    order_new =  #t3.ORDER_NEW,   
    __usn_field_order_new = #t3.USN_ORDER_NEW
   
    FROM #t3
    WHERE dbo.lion_Tasks.uid_obj = #t3.UUID_TASK
    
	   				
    UPDATE dbo.lion_Tasks_Changes_Parts
    SET 
	
    __usn_entity_cp = #t3.USN_ENTITY

    FROM  #t3
    WHERE dbo.lion_Tasks_Changes_Parts.uid_task_cp = #t3.UUID_TASK AND dbo.lion_Tasks_Changes_Parts.uid_user_cp = #t3.UUID_USER
   			   			 
 
END
GO



Отрабатывает 10-20 секунд. Пробовал еще такой вариант без temp-овой БД. Но результат тот же.

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
CREATE PROCEDURE dbo.lion_UpdateTasksNewOrder(  @Table TasksNewOrderTableType READONLY )
AS

BEGIN
	  	
    UPDATE TasksTable
    SET     

    order_new = t.ORDER_NEW,   
    __usn_field_order_new = t.USN_ORDER_NEW
   
    FROM dbo.lion_Tasks TasksTable
    INNER JOIN @Table t
    ON t.UUID_TASK = TasksTable.uid_obj
    
    UPDATE TasksTableCP
    SET 
	
    __usn_entity_cp = tcp.USN_ENTITY

    FROM dbo.lion_Tasks_Changes_Parts TasksTableCP
    INNER JOIN @Table tcp
    ON tcp.UUID_TASK = TasksTableCP.uid_task_cp AND tcp.UUID_USER = TasksTableCP.uid_user_cp
   			   			     
END
GO



Temp-овая БД находится на SSD-диске. Может кто подскажет, куда копать для ускорения?
...
Рейтинг: 0 / 0
Обновление нескольких полей у большого числа строк
    #39697979
Гавриленко Сергей Алексеевич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
gepard1980 SELECT * INTO #t3 FROM @Table

CREATE NONCLUSTERED INDEX IDX_T3_UID_TASK ON #t3(UUID_TASK)
CREATE NONCLUSTERED INDEX IDX_T3_UID_USER ON #t3(UUID_USER)Зачем? Сделайте сразу в типе TasksNewOrderTableType (через unique-констрейнты с участием сурогатного уникального поля). Так же не ясно, зачем эти индексы нужны в принципе.

Ну и планы надо смотреть.
...
Рейтинг: 0 / 0
Обновление нескольких полей у большого числа строк
    #39698007
gepard1980
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Хорошо. Индексы уберу как написали. План для варианта с join-ами прикрепил.
...
Рейтинг: 0 / 0
Обновление нескольких полей у большого числа строк
    #39698009
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
gepard1980,

Планы нужны актуальные, а не оценочные. И в формате sqlplan, а не картинками.
...
Рейтинг: 0 / 0
Обновление нескольких полей у большого числа строк
    #39698014
gepard1980
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Как их получить для хранимых процедур?
...
Рейтинг: 0 / 0
Обновление нескольких полей у большого числа строк
    #39698039
aleks222
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
gepard1980куда копать для ускорения?

Откуда уверенность, что можно "быстрее"?
Таки "10 тысяч курьеров скачутобъектов".

Рази тока вот так написать, если вероятность "обновить на то же самое" не нулевая

Код: sql
1.
2.
3.
 UPDATE tt  SET order_new = t.ORDER_NEW,   __usn_field_order_new = t.USN_ORDER_NEW
     FROM dbo.lion_Tasks as tt  INNER JOIN @Table as t ON t.UUID_TASK = tt.uid_obj
where order_new <> t.ORDER_NEW or   __usn_field_order_new <> t.USN_ORDER_NEW
...
Рейтинг: 0 / 0
Обновление нескольких полей у большого числа строк
    #39698041
Фотография alexeyvg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
gepard1980Отрабатывает 10-20 секунд. Пробовал еще такой вариант без temp-овой БД. Но результат тот же.А поля dbo.lion_Tasks.uid_obj и dbo.lion_Tasks_Changes_Parts.uid_task_cp какого типа? У первого ГУИД, и на него кластерный индекс, а второй - просто FK?

Если так, то обновление 10 000 записей есть обновление 10 000 случайных страниц, и должно делаться долго.

Вам нужно подумать над моделью данных и архитектурой системы, оптимальны ли они, ну или просто наращивать железо.

Индексы, конечно, не нужны, как и перелив в временную таблицу, это же у вас просто передача записей для обновления, сервер их должен все прочитать, и, соответственно, скан будет самым оптимальным.
...
Рейтинг: 0 / 0
Обновление нескольких полей у большого числа строк
    #39698043
Фотография alexeyvg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
aleks222Рази тока вот так написать, если вероятность "обновить на то же самое" не нулеваяДа, вот это очень важно, т.к. в данном случае медленное именно обновление, если памяти достаточно.
...
Рейтинг: 0 / 0
Обновление нескольких полей у большого числа строк
    #39698044
Фотография alexeyvg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
gepard1980Как их получить для хранимых процедур?Профайлером.
...
Рейтинг: 0 / 0
Обновление нескольких полей у большого числа строк
    #39698048
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
gepard1980Как их получить для хранимых процедур?Профайлер. Extended Events.
Либо выполнить в студии, обеспечив при вызове такие же опции соединения, язык и значения параметров.

После проблемного вызова, посмотрите в sys.dm_exec_procedure_stats данные по процедуре.
Если last_elapsed_time много больше last_worker_time - имеют место ожидания (на блокировках и т.п.).
...
Рейтинг: 0 / 0
Обновление нескольких полей у большого числа строк
    #39698076
gepard1980
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо всем кто окликнулся. Завтра пришлю актуальный план выполнения хранимой процедуры.
...
Рейтинг: 0 / 0
Обновление нескольких полей у большого числа строк
    #39698187
gepard1980
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
alexeyvggepard1980Отрабатывает 10-20 секунд. Пробовал еще такой вариант без temp-овой БД. Но результат тот же.А поля dbo.lion_Tasks.uid_obj и dbo.lion_Tasks_Changes_Parts.uid_task_cp какого типа? У первого ГУИД, и на него кластерный индекс, а второй - просто FK?

Если так, то обновление 10 000 записей есть обновление 10 000 случайных страниц, и должно делаться долго.

Вам нужно подумать над моделью данных и архитектурой системы, оптимальны ли они, ну или просто наращивать железо.

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

Перешел на вариант без использования tempdb. dbo.lion_Tasks.uid_obj - Guid (кластерный), dbo.lion_Tasks_Changes_Parts.uid_task_cp - Guid (некластерный) - просто FK. На архитектуру думаю повлиять так: если пришло больше тысячи, обрабатывать только тысячу и кидать флаг клиенту, чтобы он другие присылал объекты. Короче разбить один большой запрос на несколько. Еще попробовал к хранимой процедуре добавить WITH RECOMPILE. Буду в логах смотреть - есть ли смысл.
...
Рейтинг: 0 / 0
Обновление нескольких полей у большого числа строк
    #39698203
gepard1980
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
alexeyvggepard1980Как их получить для хранимых процедур?Профайлером.

Для данной ХП добыл следующие актуальные планы выполнения.

CREATE PROCEDURE dbo.lion_UpdateTasksNewOrder( @Table TasksNewOrderTableType READONLY) WITH RECOMPILE
AS

BEGIN

DECLARE @ErrorCode int
SET @ErrorCode = -1

UPDATE TasksTable
SET

order_new = t.ORDER_NEW,
__usn_field_order_new = t.USN_ORDER_NEW

FROM dbo.lion_Tasks TasksTable
INNER JOIN @Table t
ON t.UUID_TASK = TasksTable.uid_obj

IF( @@ERROR != 0 )
BEGIN
SET @ErrorCode = -1
GOTO Cleanup
END

UPDATE TasksTableCP
SET

__usn_entity_cp = tcp.USN_ENTITY

FROM dbo.lion_Tasks_Changes_Parts TasksTableCP
INNER JOIN @Table tcp
ON tcp.UUID_TASK = TasksTableCP.uid_task_cp AND tcp.UUID_USER = TasksTableCP.uid_user_cp

IF( @@ERROR != 0 )
BEGIN
SET @ErrorCode = -1
GOTO Cleanup
END

RETURN 0

Cleanup:

RETURN @ErrorCode

END

GO
...
Рейтинг: 0 / 0
Обновление нескольких полей у большого числа строк
    #39698211
gepard1980
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вот еще сюда закинул план: https://www.brentozar.com/pastetheplan/?id=HkkqKg6DX
...
Рейтинг: 0 / 0
Обновление нескольких полей у большого числа строк
    #39698218
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
gepard1980Для данной ХП добыл следующие актуальные планы выполнения.Это опять оценочные планы, а не актуальные.
...
Рейтинг: 0 / 0
Обновление нескольких полей у большого числа строк
    #39698227
gepard1980
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
invm, запустил SQL Profiler. Создал трассировку. Запустил код в Visual Studio. Остановил трассировку. Сохранил в файле результаты. Как правильно сделать?
...
Рейтинг: 0 / 0
Обновление нескольких полей у большого числа строк
    #39698253
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
gepard1980,

Нужно добавить в трассу событие Showplan XML Statistics Profile
...
Рейтинг: 0 / 0
Обновление нескольких полей у большого числа строк
    #39698254
TaPaK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
gepard1980,

Estimated -> Showplan XML
Actual - > Showplan XML Statistics Profile
...
Рейтинг: 0 / 0
Обновление нескольких полей у большого числа строк
    #39698257
Barclay
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
gepard1980Temp-овая БД находится на SSD-диске. Может кто подскажет, куда копать для ускорения?
Что-то должно помочь, надо тестить:
1. задействуйте минимальное логирование при записи с flag 610 и/или с хинтом TABLOCK
2.
Замените конструкцию на похожую
--Synchronize the target table with
--refreshed data from source table
MERGE Products AS TARGET
USING UpdatedProducts AS SOURCE
ON (TARGET.ProductID = SOURCE.ProductID)
--When records are matched, update
--the records if there is any change
WHEN MATCHED AND TARGET.ProductName <> SOURCE.ProductName
OR TARGET.Rate <> SOURCE.Rate THEN
UPDATE SET TARGET.ProductName = SOURCE.ProductName,
TARGET.Rate = SOURCE.Rate
--When no records are matched, insert
--the incoming records from source
--table to target table
WHEN NOT MATCHED BY TARGET THEN
INSERT (ProductID, ProductName, Rate)
VALUES (SOURCE.ProductID, SOURCE.ProductName, SOURCE.Rate)
--When there is a row that exists in target table and
--same record does not exist in source table
--then delete this record from target table
WHEN NOT MATCHED BY SOURCE THEN
DELETE
...
Рейтинг: 0 / 0
Обновление нескольких полей у большого числа строк
    #39698261
TaPaK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
gepard1980
вообще table variable то ещё зло, пробуйте прибить RECOMPILE, но всё же план

Barclay,
да именно merge и решает проблемы производительности, только в другу сторону
...
Рейтинг: 0 / 0
Обновление нескольких полей у большого числа строк
    #39698262
gepard1980
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
TaPaK, выставил эти две галки. Получил то что на прикрепленном скриншоте.

Сюда план положил: https://www.brentozar.com/pastetheplan/?id=Bygm2bTDQ
...
Рейтинг: 0 / 0
Обновление нескольких полей у большого числа строк
    #39698267
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
gepard1980TaPaK, выставил эти две галки.Одна галка нужна - Showplan XML Statistics Profile
А не Showplan Statistics Profile
...
Рейтинг: 0 / 0
Обновление нескольких полей у большого числа строк
    #39698274
gepard1980
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
invm, вот теперь только с этой галкой. Планы прикрепил.
...
Рейтинг: 0 / 0
Обновление нескольких полей у большого числа строк
    #39698282
gepard1980
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
gepard1980, вот получил актуальные планы.
...
Рейтинг: 0 / 0
Обновление нескольких полей у большого числа строк
    #39698286
gepard1980
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
TaPaK
вообще table variable то ещё зло, пробуйте прибить RECOMPILE, но всё же план


Дак а как без table variable? Не по одной же записи обновлять.
...
Рейтинг: 0 / 0
Обновление нескольких полей у большого числа строк
    #39698308
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
gepard1980,

План нужен для проблемного вызова, который 10-20 сек длится.
...
Рейтинг: 0 / 0
Обновление нескольких полей у большого числа строк
    #39698311
gepard1980
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
invm, а как получить его на боевом сервере? Там же 2 тысячи транзакции в секунду идет. Как выцепить нужную строчку из тонны строк в профайлере?
...
Рейтинг: 0 / 0
Обновление нескольких полей у большого числа строк
    #39698366
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
gepard1980invm, а как получить его на боевом сервере? Там же 2 тысячи транзакции в секунду идет.Я вам уже писал - 21664588
Выполнить процедуру в SSMS с установленным set statistics xml on, обеспечив идентичные с проблемным вызовом опции соединения, язык и значения параметров.
Совет про sys.dm_exec_procedure_stats вы тоже игногрируете...
...
Рейтинг: 0 / 0
Обновление нескольких полей у большого числа строк
    #39698898
gepard1980
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
invm, спасибо! Буду пробовать.
...
Рейтинг: 0 / 0
Обновление нескольких полей у большого числа строк
    #39699219
Фотография Mind
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Запрос настолько тривиальный, что не понятно, что все так хотят увидеть в актуальном плане. Табличная переменная всегда будет loop-иться к другим таблицам, быстрее все равно никак. merge или hash на 20-миллионную таблицу явно быстрее не будет.

Насчет "обновить на то же самое", разве сервер будет физически обновлять? Вроде там какя то оптимизация есть для таких случаев.

Я бы предложил собрать больше информации, хотя бы, как уже предложили, из sys.dm_exec_procedure_stats, ну и ожидания было бы неплохо. И вообще может оказаться что там кто-то блокирует постоянно.
...
Рейтинг: 0 / 0
Обновление нескольких полей у большого числа строк
    #39699225
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MindЗапрос настолько тривиальный, что не понятно, что все так хотят увидеть в актуальном плане.Лично я хочу увидеть сколько строк реально обновляется.
У ТС 10000 строк на входе, а обновляться может и несколько миллионов...
...
Рейтинг: 0 / 0
Обновление нескольких полей у большого числа строк
    #39699249
aleks222
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MindНасчет "обновить на то же самое", разве сервер будет физически обновлять? Вроде там какя то оптимизация есть для таких случаев.


Перекрестись.

Код: sql
1.
2.
3.
4.
5.
declare @t table (s nvarchar(100) collate ...CI_AS);

insert @t values('Вот хрен тебе.')

update @t set s = 'Вот хрен Тебе.'



Это тривиальный пример эквивалентного, но неэквивалентного обновления.
Сервер не размышляет.
...
Рейтинг: 0 / 0
32 сообщений из 32, показаны все 2 страниц
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Обновление нескольких полей у большого числа строк
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]