2009-03-02 85 views
1

我有這個查詢是很長的,但添加一個where子句,或加入一個字符串使它需要額外的2秒運行。我無法弄清楚爲什麼。加入varchar(50)外鍵減慢查詢

下面是完整的查詢:

inner join [lookup] l on p.dosing = l.lookupid and l.lookupid = 'da_ncd' 

此外,它移動到where條款具有相同的效果:

where p.dosing = 'da_ncd' 

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 

減慢下來是線

否則,查詢幾乎立即運行。 >.<

+0

is l.lookupid索引? – sfossen 2009-03-02 20:26:06

+0

是的,它的主鍵 – Shawn 2009-03-02 20:26:27

回答

2

啊,對不起,我想通了。 Patient.Dosing被設置爲允許空值。我想這是一種不同的索引。

0

嘗試在該表上創建一個索引,並確保在該字段列表中正確包含該VARCHAR字段。

2

爲了記錄,即使問題得到解答。 通常情況下會發生這種情況,因爲執行計劃已更改。比較查詢分析器中的計劃。

2

另一個問題是數據類型 - 如果p.dosing和l.lookupid不同 - 例如,nvarchar與varchar可能會產生巨大影響。