我在Booking和SMSConfiguration中使用以下查询来匹配基于CategoryId的记录。
这里我需要在SMSConfiguration中找到NULL CategoryId的记录。我得到了我预期的输出。但查询运行2分钟。
如果我在JOIN中移除附加条件OR SMS.CategoryId IS NULL
,它运行得更快且不到1秒。我不知道如何将其移出JOIN。
SELECT SMS.Id AS ConfigId
,B.BookingId AS BookingId
,B.StartTime AS BookingStartTime
,B.EndTime AS BookingEndTime
,B.BookingDate AS BookingDate
,B.Price AS Price
FROM Booking B
INNER JOIN SMSConfiguration SMS ON SMS.CategoryId = B.CategoryId
OR SMS.CategoryId IS NULL -- CAUSING SLOW
AND SMS.TenantId = B.TenantId
修改
完整查询
DECLARE @CurrentDateTime SMALLDATETIME
SET @CurrentDateTime='2016-08-11 08:00:00.247'
SELECT SMS.Id AS ConfigId
,B.BookingId AS BookingId
,B.StartTime AS BookingStartTime
,B.EndTime AS BookingEndTime
,B.BookingDate AS BookingDate
,B.Price AS Price
,C.CategoryName AS CategoryName
,PER.PersonId AS PersonId
,P.PatientId AS PatientId
,PER.FirstName AS PatientFirstName
,PER.LastName AS PatientLastName
,PER.MobileNumber AS PatientMobileNumber
,RP.FirstName AS DoctorFirstName
,RP.LastName AS DoctorLastName
,SMS.SMSText
,B.TenantId AS TenantId
FROM Booking B
INNER JOIN SMSConfiguration SMS ON SMS.CategoryId = B.CategoryId
OR SMS.CategoryId IS NULL
AND SMS.TenantId = B.TenantId
INNER JOIN Tenant T ON T.TenantId = B.TenantId --AND T.IsSMSEnabled=1
INNER JOIN Patient P ON B.PatientId = P.PatientId
INNER JOIN Person PER ON P.PersonId = PER.PersonId
INNER JOIN Person RP ON RP.PersonId = B.ResponsiblePersonId
LEFT JOIN Category C ON C.CategoryId = B.CategoryId
WHERE
PER.MobileNumber IS NOT NULL
AND PER.MobileNumber <> ''
AND (
(
(
DATEDIFF(DAY, @CurrentDateTime, B.StartTime) = SMS.Duration
AND SMS.DurationType = 1
)
OR (
DATEDIFF(DAY, @CurrentDateTime, B.StartTime) = SMS.Duration * 7
AND SMS.DurationType = 2
)
OR (
DATEDIFF(DAY, @CurrentDateTime, B.StartTime) = SMS.Duration * 30
AND SMS.DurationType = 3
)
)
AND BeforeAfter = 0
OR (
(
(
DATEDIFF(DAY, B.StartTime, @CurrentDateTime) = SMS.Duration
AND SMS.DurationType = 1
)
OR (
DATEDIFF(DAY, @CurrentDateTime, B.StartTime) = SMS.Duration * 7
AND SMS.DurationType = 2
)
OR (
DATEDIFF(DAY, @CurrentDateTime, B.StartTime) = SMS.Duration * 30
AND SMS.DurationType = 3
)
)
AND BeforeAfter = 1
)
)
慢速计划
当我评论OR SMS.CategoryId为空时,快速计划
答案 0 :(得分:1)
将SMS.CategoryId和B.CategoryId放在WHERE条件中,然后检查null - 它的可读性更强。尝试运行以下查询,它将表迭代周期减少1
SELECT
SMS.Id AS ConfigId
,B.BookingId AS BookingId
,B.StartTime AS BookingStartTime
,B.EndTime AS BookingEndTime
,B.BookingDate AS BookingDate
,B.Price AS Price
FROM
Booking B
INNER JOIN SMSConfiguration SMS
ON SMS.TenantId = B.TenantId
WHERE
B.CategoryId = ISNULL(SMS.CategoryId,B.CategoryId)
答案 1 :(得分:1)
OR几乎总是很慢。通常使用UNION all查询要快得多。但是,我不清楚确切的连接条件应该是什么。你的意思是:
INNER JOIN SMSConfiguration SMS ON (SMS.CategoryId = B.CategoryId
OR SMS.CategoryId IS NULL)
AND SMS.TenantId = B.TenantId
或者
INNER JOIN SMSConfiguration SMS ON SMS.CategoryId = B.CategoryId
OR (SMS.CategoryId IS NULL
AND SMS.TenantId = B.TenantId)
第一个是你得到的,但即使你的意思是,你应该使用()在有人去维护时明确说明。