Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Обновление нескольких полей у большого числа строк / 25 сообщений из 32, страница 1 из 2
04.09.2018, 17:30
    #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
04.09.2018, 17:35
    #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
04.09.2018, 18:15
    #39698007
gepard1980
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обновление нескольких полей у большого числа строк
Хорошо. Индексы уберу как написали. План для варианта с join-ами прикрепил.
...
Рейтинг: 0 / 0
04.09.2018, 18:18
    #39698009
invm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обновление нескольких полей у большого числа строк
gepard1980,

Планы нужны актуальные, а не оценочные. И в формате sqlplan, а не картинками.
...
Рейтинг: 0 / 0
04.09.2018, 18:21
    #39698014
gepard1980
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обновление нескольких полей у большого числа строк
Как их получить для хранимых процедур?
...
Рейтинг: 0 / 0
04.09.2018, 18:52
    #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
04.09.2018, 18:59
    #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
04.09.2018, 19:00
    #39698043
alexeyvg
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обновление нескольких полей у большого числа строк
aleks222Рази тока вот так написать, если вероятность "обновить на то же самое" не нулеваяДа, вот это очень важно, т.к. в данном случае медленное именно обновление, если памяти достаточно.
...
Рейтинг: 0 / 0
04.09.2018, 19:01
    #39698044
alexeyvg
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обновление нескольких полей у большого числа строк
gepard1980Как их получить для хранимых процедур?Профайлером.
...
Рейтинг: 0 / 0
04.09.2018, 19:06
    #39698048
invm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обновление нескольких полей у большого числа строк
gepard1980Как их получить для хранимых процедур?Профайлер. Extended Events.
Либо выполнить в студии, обеспечив при вызове такие же опции соединения, язык и значения параметров.

После проблемного вызова, посмотрите в sys.dm_exec_procedure_stats данные по процедуре.
Если last_elapsed_time много больше last_worker_time - имеют место ожидания (на блокировках и т.п.).
...
Рейтинг: 0 / 0
04.09.2018, 20:03
    #39698076
gepard1980
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обновление нескольких полей у большого числа строк
Спасибо всем кто окликнулся. Завтра пришлю актуальный план выполнения хранимой процедуры.
...
Рейтинг: 0 / 0
05.09.2018, 08:35
    #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
05.09.2018, 09:35
    #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
05.09.2018, 09:45
    #39698211
gepard1980
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обновление нескольких полей у большого числа строк
Вот еще сюда закинул план: https://www.brentozar.com/pastetheplan/?id=HkkqKg6DX
...
Рейтинг: 0 / 0
05.09.2018, 09:59
    #39698218
invm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обновление нескольких полей у большого числа строк
gepard1980Для данной ХП добыл следующие актуальные планы выполнения.Это опять оценочные планы, а не актуальные.
...
Рейтинг: 0 / 0
05.09.2018, 10:13
    #39698227
gepard1980
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обновление нескольких полей у большого числа строк
invm, запустил SQL Profiler. Создал трассировку. Запустил код в Visual Studio. Остановил трассировку. Сохранил в файле результаты. Как правильно сделать?
...
Рейтинг: 0 / 0
05.09.2018, 10:43
    #39698253
invm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обновление нескольких полей у большого числа строк
gepard1980,

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

Estimated -> Showplan XML
Actual - > Showplan XML Statistics Profile
...
Рейтинг: 0 / 0
05.09.2018, 10:51
    #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
05.09.2018, 10:58
    #39698261
TaPaK
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обновление нескольких полей у большого числа строк
gepard1980
вообще table variable то ещё зло, пробуйте прибить RECOMPILE, но всё же план

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

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


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


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