Присоединение к внешнему ключу varchar (50) замедляет запрос - PullRequest
1 голос
/ 02 марта 2009

У меня есть этот запрос, который довольно длинный, но добавление к нему предложения 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'

В противном случае запрос выполняется практически мгновенно. >.<

Ответы [ 4 ]

2 голосов
/ 02 марта 2009

Другой недостаток - типы данных - если p.dosing и l.lookupid различаются - например, nvarchar и varchar могут оказать огромное влияние.

2 голосов
/ 02 марта 2009

Ах, прости, я понял это. Пациент. Дозирование было установлено как разрешенное значение null. Я думаю, это сделало индекс другого рода.

2 голосов
/ 02 марта 2009

Для записи, хотя ответ на вопрос. Обычно такие вещи случаются, потому что план выполнения меняется. Сравните планы в анализаторе запросов.

0 голосов
/ 02 марта 2009

Попробуйте создать индекс для этой таблицы, убедившись, что вы правильно включили это поле VARCHAR в список полей.

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