Несколько соединений SQL Server облагают налогом процессор - PullRequest
1 голос
/ 13 апреля 2010

У меня есть хранимая процедура на SQL Server 2005. Она извлекается из функции Table и имеет два соединения. Когда запрос выполняется с использованием нагрузочного теста, он убивает процессор на 100% по всем 16 ядрам! Я определил, что при удалении одного из соединений запрос выполняется нормально, но оба нагружают процессор.

 Select 
  SKey
 From 
  dbo.tfnGetLatest(@ID) a 
  left join [STAGING].dbo.RefSrvc b on 
   a.LID = b.ESIID
  left join [STAGING].dbo.RefSrvc c on 
   a.EID = c.ESIID 

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

Ответы [ 4 ]

2 голосов
/ 13 апреля 2010

Это может пролить свет на проблему. Можете ли вы выделить первое соединение в CTE?

Примерно так:

with FirstJoin(SKey,EID) as ( select a.Skey,a.EID from dbo.tfnGetLatest(@ID) a left join [STAGING].dbo.RefSrvc b on a.LID = b.ESIID )</p> <p>select Skey from FirstJoin fj left join [STAGING].dbo.RefSrvc c on fj.EID = c.ESIID

Кроме того, поскольку оба ваших объединения являются левыми, как они сужают набор результатов? Разве этот запрос не эквивалентен select sKey from dbo.tfnGetLatest(@ID)?

1 голос
/ 13 апреля 2010

Что возвращает dbo.tfnGetLatest(@ID) и является ли оно встроенным табличным значением или мульти-оператором?

Если это мульти-оператор, то

  • это черный ящик для оптимизатора
  • кардинальность равна единице
  • нет статистики по результатам udf

Пожалуйста, посмотрите мой ответ здесь, почему udfs могут быть плохими

0 голосов
/ 13 апреля 2010

Это было бы намного яснее с небольшим количеством выходных данных, но я подскочу. Что это делает для вас?

SELECT SKey FROM dbo.tfnGetLatest(@ID)
WHERE LID IN
    (SELECT ESIID from [STAGING].dbo.RefSrvc)
AND EID IN
    (SELECT ESIID FROM [STAGING].dbo.RefSrvc)
0 голосов
/ 13 апреля 2010

Так в чем же разница в вашем плане выполнения? Это даже с использованием индекса?

Пытались ли вы использовать вместо этого UNION all (я предполагаю, что вы пытаетесь получить записи, имеющие тот или иной идентификатор, который не может дать ваш текущий запрос; все, что вы предоставляете, представляет собой полный список всех Значения skey, для этого вообще не нужно присоединяться.)

Select  
    SKey 
From  
    dbo.tfnGetLatest(@ID) a  
    left join [STAGING].dbo.RefSrvc b on  
        a.LID = b.ESIID 
union all
Select  
    SKey 
From  
    dbo.tfnGetLatest(@ID) d  
    left join [STAGING].dbo.RefSrvc c on  
        d.EID = c.ESIID  

Тем не менее может быть неэффективным, если он не использует индекс, но, вероятно, вернет лучший набор записей.

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

...