我有这个查询很长,但是为它添加一个where子句,或者连接一个字符串使得运行需要额外的2秒。我无法弄清楚原因。
这是完整的查询:
ALTER PROCEDURE [dbo].[RespondersByPracticeID]
@practiceID int = null,
@activeOnly bit = 1
AS
BEGIN
SET NOCOUNT ON;
select
isnull(sum(isResponder),0) as [Responders]
,isnull(count(*) - sum(isResponder),0) as [NonResponders]
,isnull((select
count(p.patientID)
from patient p
inner join practice on practice.practiceid = p.practiceid
inner join [lookup] l on p.dosing = l.lookupid and l.lookupid = 'da_ncd'
where
p.practiceID = isnull(@practiceID, p.practiceID)
and p.active = case @activeOnly when 1 then 1 else p.active end
) - (isnull(sum(isResponder),0) + isnull(count(*) - sum(isResponder),0)),0)
as [Undetermined]
from (
select
v.patientID
,firstVisit.hbLevel as startHb
,maxHbVisit.hblevel as maxHb
, case when (maxHbVisit.hblevel - firstVisit.hbLevel >= 1) then 1 else 0 end as isResponder
,count(v.patientID) as patientCount
from patient p
inner join visit v on v.patientid = v.patientid
inner join practice on practice.practiceid = p.practiceid
inner join [lookup] l on p.dosing = l.lookupid and l.lookupid = 'da_ncd'
inner join (
SELECT
p.PatientID
,v.VisitID
,v.hblevel
,v.VisitDate
FROM Patient p
INNER JOIN Visit v ON p.PatientID = v.PatientID
WHERE
v.VisitDate = (
SELECT MIN(VisitDate)
FROM Visit
WHERE PatientId = p.PatientId
)
) firstVisit on firstVisit.patientID = v.patientID
inner join (
select
p.patientID
,max(v.hbLevel) as hblevel
from Patient p
INNER JOIN Visit v ON p.PatientID = v.PatientID
group by
p.patientID
) MaxHbVisit on maxHbVisit.patientid = v.patientId
where
p.practiceID = isnull(@practiceID, p.practiceID)
and p.active = case @activeOnly when 1 then 1 else p.active end
group by
v.patientID
,firstVisit.hbLevel
,maxHbVisit.hblevel
having
datediff(
d,
dateadd(
day
,-DatePart(
dw
,min(v.visitDate)
) + 1
,min(v.visitDate)
)
, max(v.visitDate)
) >= (7 * 8) -- Eight weeks.
) responders
END
减慢速度的行是:
inner join [lookup] l on p.dosing = l.lookupid and l.lookupid = 'da_ncd'
此外,将其移至where
子句具有相同的效果:
where p.dosing = 'da_ncd'
否则,查询几乎立即运行。 >.<
答案 0 :(得分:2)
啊,对不起我弄清楚了。 Patient.Dosing被设置为允许空值。我想这使它成为一种不同的索引。
答案 1 :(得分:2)
记录中,即使问题得到解答。 通常这样的事情会发生,因为执行计划已经改变。比较查询分析器中的计划。
答案 2 :(得分:2)
另一个问题是数据类型 - 如果p.dosing和l.lookupid不同 - 例如,nvarchar与varchar会产生巨大的影响。
答案 3 :(得分:0)
尝试在该表上创建索引,确保在字段列表中正确包含该VARCHAR字段。