powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Обновление нескольких полей у большого числа строк
25 сообщений из 32, страница 1 из 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
25 сообщений из 32, страница 1 из 2
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Обновление нескольких полей у большого числа строк
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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