powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Посоветуйте как оптимизировать
5 сообщений из 5, страница 1 из 1
Посоветуйте как оптимизировать
    #32042990
Michael Hopgarden
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
7.0 SP 3
Код: plaintext
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.
32.
33.
34.
create table dbo.Assets (
   id int identity constraint PK__Assets__id primary key,
   list_id int not null constraint FK__Assets__list_id foreign key references dbo.Lists(id),
...)

create procedure My_outer
as
...
   create table #AcAsYMD (
      account_id int not null,
      asset_id int not null,
      yyyymmdd int not null,
      primary key (account_id, asset_id, yyyymmdd),
      list_id,
   ...)
   insert #AcAsYMD ...
   exec @return = My_inner
...
 --end procedure My_outer
 
create procedure My_inner
as
   begin tran 
...
      update #AcAsYMD 
         set
         list_id = s.list_id
         from
         #AcAsYMD as a
         inner join
         dbo.Assets as s
         on
      s.id = a.asset_id
...
--end procedure My_inner

И план то, как мне кажется, оптимальный.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
Clustered Index Update(OBJECT:([tempdb].[dbo].[#AcAsYMD_].[PK__#AcAsYMD__2FCD1BAF]), 
SET:([#AcAsYMD].[list_id]=[s].[list_id]))
  | --Top(ROWCOUNT est 0)
 
       | --Nested Loops(Inner Join)
 
            | --Clustered Index Scan(OBJECT:([tempdb].[dbo].[#AcAsYMD_].[PK__#AcAsYMD__2FCD1BAF] AS [a]))
 
            | --Clustered Index Seek(OBJECT:([#TEST1#].[dbo].[Assets].[PK__Assets__id] AS [s]), 
 
SEEK:([s].[id]=[a].[asset_id]) ORDERED)

А, продолжительность исполнения инструкции update чуть ли не на порядок больше, чем продолжительности исполнения остальных инструкций в процедурах.
Приходит на ум только, заменить #AcAsYMD постоянной таблицей AcAsYMD, и в My_outer, вместо создания временной таблицы, delete AcAsYMD.
Если у кого есть другие соображения, прошу поделиться.
...
Рейтинг: 0 / 0
Посоветуйте как оптимизировать
    #32043072
mikosha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Clustered Index Scan - eto je to je samoe chto i Table scan.
Esli tvoiya table ob'emnaya to eto zanimaet mnogo vremeni.
Poprobui zamenit' clustred index na unique.Mojet pomojet.
...
Рейтинг: 0 / 0
Посоветуйте как оптимизировать
    #32043103
Michael Hopgarden
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Таблицу по которой идет Clustered Index Scan мы как раз и обновляем. При тестировании содержала всего 2 записи. Assets меньше 1000. Поэтому, как мне кажется, сканирование даже полезно. И следовательно проблема не в этом.
Да, к стати, транзакция открывается во внешней, а не во внутренней процедуре.
...
Рейтинг: 0 / 0
Посоветуйте как оптимизировать
    #32043106
KonstN
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всё у тебя в порядке.
Дальше уже можно только вылизывать.
На самом деле, так как ты не задаёшь никаких WHERE на #AcAsYMD при апдейте, то работает только scan, для не range доступа это самый лучший доступ. Возможно table scan здесь был бы даже предпочтительнее, потому что после нахождения индекса нужно ещё слазить в страницы данных и поменять значение list_id там. Попробуй принудительно сказать table scan. Или можно попробовать сделать кластерный индекс на (asset_id, list_id), соответственно, делая primary key не с кластерным индексом. Хотя не уверен, что это поможет. Тут простой table scan всё равно будет лучше. Тогда можно ещё в primary key добавить list_id. Короче говоря, поиграть с кластерным индексом.
Или если размеры таблицы не очень велики, то попробуй сделать primary key (asset_id, account_id, yyyymmdd) - может заджойнит, не гоняя nested loops.
Ещё это может помочь в том случае, если update выполняется путём последовательных delete/insert (что чаще всего). В 7.0, конечно, нет вроде бы проблем с блокировками при insertе, но всё-таки кластерный индекс определяет порядок физического размещения данных в таблице, и delete/insertы могут быстрее проезжать.
И ещё, когда у тебя insert идёт, то посмотри в каком порядке у тебя подаются значения, участвующие в кластерном индексе. Я бы сказал, что insert должен быть дольше, чем update однозначно.
Но вот что мне не нравится, так это begin tran в процедуре. Оно надо? Лучше не стОит, мне кажется. Вот не в этом ли проблема долгого апдейта? Не ждёт она у тебя ничего, а? Блокировочки посмотри.

2 mikosha
Кластерный индекс может быть уникальным и неуникальным, и наоборот. Уникальность здесь не при чём.
...
Рейтинг: 0 / 0
Посоветуйте как оптимизировать
    #32043162
Michael Hopgarden
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Именно, вылизыванием и занимаюсь. Без begin tran нельзя. Открываю только одну во внешней процедуре. В первом сообщении просто не там написал. Блокировок нет. Тестовая база. Соединение одно, в котором и отлаживается процедура. И проблема, на мой взгляд, возникает, когда временная таблица, созданная во внешней процедуре, первый раз встречается во внутренней. Следующие инструкции, использующие эту временную таблицу, исполняются быстро, как и положено. Самая внешняя процедура, которая и обернута транзакцией, вызывает внутренние, которые сами могут содержать вызовы "еще более" внутренних процедур. И везде, где во внутренней процедуре первый раз встречается инструкция на модификацию временной таблицы, созданной в процедуре более высокого уровня, наблюдаются тормоза. Приведенный пример самый простой. Stmt duration 571 (в чем их там профайлер измеряет) против 10 - 20 для прочих инструкций включающих эту таблицу.
...
Рейтинг: 0 / 0
5 сообщений из 5, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Посоветуйте как оптимизировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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