Время выполнения запроса SQL Server слишком медленное - PullRequest
0 голосов
/ 10 октября 2019

Мне пришлось внести коррективы в запрос, который интенсивно используется в моей организации. В основном, «Основной запрос» не набирал обороты за ночь. Я добавил в части #DoubleShifts и #CombinedShifts. Они находят все смены, которые были завершены в одночасье. Мои изменения работают, но теперь время выполнения запроса превышает 3 минуты из 10 секунд, и это не сработает.

Я просто ищу полезные советы для оптимизации этого запроса на скорость.

Спасибо.

-- variables
DECLARE @dateFrom DATETIME
DECLARE @dateTo DATETIME

SET @dateFrom = '03/24/2019 00:00:00'
SET @dateTo = '03/24/2019 23:59:59'

IF OBJECT_ID ('tempdb..#DoubleShifts') IS NOT NULL
DROP TABLE #DoubleShifts

IF OBJECT_ID ('tempdb..#CombinedSchedules') IS NOT NULL
DROP TABLE #CombinedSchedules

IF OBJECT_ID ('tempdb..#callsvsAideDetailsReport') IS NOT NULL
DROP TABLE #callsvsAideDetailsReport

-- Double Shifts
SELECT
s1.ID AS ID1,s2.ID as ID2, s1.Provider1Code, s1.FromDateTime, 
s2.ToDateTime, s1.ClientID, s1.EmpID, s1.Deleted

INTO #DoubleShifts

FROM EMR.dbo.ScheduleOfService s1, 
EMR.dbo.ScheduleOfService s2, EMR.dbo.Patients p

WHERE  
s2.FromDateTime >= @dateFrom
AND s2.ToDateTime <= @dateTo 
AND s1.ToDateTime = s2.FromDateTime
AND s1.ClientID = p.ID
AND s1.SCProg = 'H'
AND s1.ClientID = s2.ClientID
AND s1.EmpID = s2.EmpID
AND s1.Deleted = 'False'
AND s2.Deleted = 'False'
AND p.IsHospice <> 1
AND s1.Provider1Code = s2.Provider1Code

-- Schedules
SELECT ID, Provider1Code, FromDateTime, ToDateTime, ClientID, EmpID, 
       Deleted 

INTO #CombinedSchedules 

FROM EMR..ScheduleOfService s

WHERE 
FromDateTime BETWEEN @dateFrom AND @dateTo AND Deleted = 'False' 
AND s.ID NOT IN ( SELECT ID1 FROM #DoubleShifts ) 
AND s.ID NOT IN ( SELECT ID2 FROM #DoubleShifts )

UNION ALL

SELECT ID1 as ID, Provider1Code, FromDateTime, ToDateTime, ClientID, 
       EmpID, Deleted 

FROM #DoubleShifts

-- Main Query
SELECT
CASE WHEN p.Office <> '356' THEN ob.Office
     ELSE CASE WHEN p.TeamPatient IN ('TEAM07', 'Team09', 'Team10') THEN 
     '(01) Person1'
ELSE CASE WHEN p.TeamPatient IN ('TEAM01', 'Team02', 'Team03' ) THEN 
     '(01) Person2'
ELSE p.Team 
END END END Office,
p.CO_ORD, 
eb.id1 'Aide ID1', 
eb.[Last], 
eb.[First], 
s.Provider1Code, 
p.id1 'Member ID1', 
p.LastName, 
p.FirstName, 
s.FromDateTime,

(SELECT MAX(realizeddate) FROM EMR..compliance c
 WHERE c.EmpID = eb.id
 AND c.SubType = 'Spec1'
 AND c.RealizedDate > '03/31/2018') AS 1Date,

(SELECT MAX(realizeddate) FROM EMR..compliance c
WHERE c.EmpID = eb.id
AND c.SubType = 'Spec2'
AND c.RealizedDate > '03/31/2018') AS 2Date, 

(SELECT TOP 1 TAS_MasterId FROM db..EMR_Process
 WHERE CAST(SavedDate AS DATE) BETWEEN CAST(s.FromDateTime AS DATE) 
 AND CAST(s.ToDateTime AS DATE)
 AND s.ClientID = EMR_ID) AS [OAR_ID]

 INTO #callsvsAideDetailsReport

FROM 
#CombinedSchedules s,
EMR..Offices_Base ob, 
EMR..Patients p, 
EMR..Employees_Base eb, 
EMR..Providers pro

WHERE 
s.EmpID = eb.ID
AND s.ClientID = p.id
AND p.Office = ob.OfficeCode
AND p.IsHospice <> 1
AND p.BillTo1 = pro.Code
AND p.BillTo1 NOT IN ('Hospice', 'CHOSPITAL,'NON-BILLABLE')
AND pro.BillTypeID NOT IN (3, 10, 20, 25)
AND s.Deleted = 'false'
AND eb.Active = 1
AND NOT p.id IN ('261110') -- nonbillable
AND NOT p.office IN ('85','95','99','357','158','153','130','111','83')
--AND s.FromDateTime BETWEEN @dateFrom and @dateTo -- End one day later 
      then the desired date range

ORDER BY 
ob.Office, p.CO_ORD, eb.[Last], eb.[first], s.Provider1Code, p.LastName, 
p.FirstName

-- TEMP TABLE
SELECT *

FROM #callsvsAideDetailsReport

ORDER BY Office, CO_ORD, [Last], [First], Provider1Code, LastName, 
         FirstName

Нет сообщений об ошибках. Время выполнения занимает более 3 минут. Я бы хотел, чтобы результат был не менее 20 секунд.

План запроса

1 Ответ

0 голосов
/ 10 октября 2019

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

  • У вас есть пара NOT IN, и я бы переделал их в методы полусоединения (EXISTS). Это позволит вам выполнить только частичную проверку соответствия, а не полное сравнение.

http://www.gregreda.com/2013/06/03/join-vs-exists-vs-in/

И s.ID NOT IN (ВЫБЕРИТЕ ID1 ИЗ #DoubleShifts) И s.ID НЕ ВХОДИТ (ВЫБЕРИТЕ ID2 ИЗ #DoubleShifts)

В целом, я бы по возможности избегал использования операторов «IN», но это только практическое правило, и не всегда так.

  • У вас также есть оператор order by в конце вашей последней вставки во временную таблицу. Я либо удалил вставку во временную таблицу, либо удалил порядок, а затем возвратил отсортированную временную таблицу. Вам не нужно сортировать данные перед тем, как вставить их во временную таблицу, поскольку для вас не имеет значения порядок вставки.

Это то, что я вижу сейчас. Удачи!

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