1

У меня есть таблица, которая содержит 130000 записей, но без индексирования, и я написал запрос, который имеет 4 LEFT OUTER JOINs.Улучшение производительности запросов с использованием SQL Server 2012?

Запрос работает нормально, без каких-либо проблем. Моя единственная забота - производительность, для получения результатов требуется 5-10 минут. Итак, мой вопрос в том, как я могу улучшить производительность запроса? Мой второй вопрос: нужно ли добавлять индексы? Если да, какой индекс я должен добавить, кластер или не кластер?

Мой запрос:

SELECT Z.* FROM 
(SELECT 
YTD.Specialisation, 
YTD.SpecialisationCode, 
ROUND(COALESCE(Today.Revenue_Today,0),0)Revenue_Today, 
ROUND(COALESCE(MTD.Revenue_MTD,0),0)Revenue_MTD, 
ROUND(COALESCE(YTD.Revenue_YTD,0),0)Revenue_YTD, 
ROUND(COALESCE(DTD.Revenue_DTD,0),0)Revenue_DTD, 

ROUND(COALESCE(Today.Amount1_Today,0),0)Amount1_Today, 
ROUND(COALESCE(MTD.Amount1_MTD,0),0)Amount1_MTD, 
ROUND(COALESCE(YTD.Amount1_YTD,0),0)Amount1_YTD, 
ROUND(COALESCE(DTD.Amount1_DTD,0),0)Amount1_DTD, 

ROUND(COALESCE(Today.Amount2_Today,0),0)Amount2_Today, 
ROUND(COALESCE(MTD.Amount2_MTD,0),0)Amount2_MTD, 
ROUND(COALESCE(YTD.Amount2_YTD,0),0)Amount2_YTD, 
ROUND(COALESCE(DTD.Amount2_DTD,0),0)Amount2_DTD, 

ROUND(COALESCE(Today.Amount3_Today,0),0)Amount3_Today, 
ROUND(COALESCE(MTD.Amount3_MTD,0),0)Amount3_MTD, 
ROUND(COALESCE(YTD.Amount3_YTD,0),0)Amount3_YTD, 
ROUND(COALESCE(DTD.Amount3_DTD,0),0)Amount3_DTD, 

ROUND(COALESCE(Today.Amount4_Today,0),0)Amount4_Today, 
ROUND(COALESCE(MTD.Amount4_MTD,0),0)Amount4_MTD, 
ROUND(COALESCE(YTD.Amount4_YTD,0),0)Amount4_YTD, 
ROUND(COALESCE(DTD.Amount4_DTD,0),0)Amount4_DTD, 

ROUND(COALESCE(Today.Amount5_Today,0),0)Amount5_Today, 
ROUND(COALESCE(MTD.Amount5_MTD,0),0)Amount5_MTD, 
ROUND(COALESCE(YTD.Amount5_YTD,0),0)Amount5_YTD, 
ROUND(COALESCE(DTD.Amount5_DTD,0),0)Amount5_DTD 


FROM 
(select 
a.SpecialisationCode, 
a.Specialisation, 
SUM(a.DoctorFee)Revenue_YTD, 
SUM(a.Amount1)Amount1_YTD, 
SUM(a.Amount2)Amount2_YTD, 
SUM(a.Amount3)Amount3_YTD, 
SUM(a.Amount4)Amount4_YTD, 
SUM(a.Amount5)Amount5_YTD 
from tbl_doctor a 
where FORMAT((CONVERT(smalldatetime,a.BillDate,111)),'yyyy-MM-dd') >= FORMAT((CONVERT(smalldatetime,'2012-04-01',111)),'yyyy-04-01') 
AND FORMAT((CONVERT(smalldatetime,a.BillDate,111)),'yyyy-MM-dd') <= '2012-05-01' 
and a.SpecialisationCode!=0 
and a.Specialisation NOT IN (' ') 
GROUP BY a.SpecialisationCode,a.Specialisation)YTD 



LEFT OUTER JOIN 

(select 
a.SpecialisationCode, 
a.Specialisation, 
SUM(a.DoctorFee)Revenue_DTD, 
SUM(a.Amount1)Amount1_DTD, 
SUM(a.Amount2)Amount2_DTD, 
SUM(a.Amount3)Amount3_DTD, 
SUM(a.Amount4)Amount4_DTD, 
SUM(a.Amount5)Amount5_DTD 
from tbl_doctor a 
where FORMAT((CONVERT(smalldatetime,a.BillDate,111)),'yyyy-MM-dd') >= '2012-04-01' 
    AND FORMAT((CONVERT(smalldatetime,a.BillDate,111)),'yyyy-MM-dd') <= '2012-05-01' 
and a.SpecialisationCode!=0 
and a.Specialisation NOT IN (' ') 
GROUP BY a.SpecialisationCode,a.Specialisation)DTD 
ON DTD.SpecialisationCode=YTD.SpecialisationCode 

LEFT OUTER JOIN 


(select 
a.SpecialisationCode, 
a.Specialisation, 
SUM(a.DoctorFee)Revenue_MTD, 
SUM(a.Amount1)Amount1_MTD, 
SUM(a.Amount2)Amount2_MTD, 
SUM(a.Amount3)Amount3_MTD, 
SUM(a.Amount4)Amount4_MTD, 
SUM(a.Amount5)Amount5_MTD 
from tbl_doctor a 
where FORMAT((CONVERT(smalldatetime,a.BillDate,111)),'yyyy-MM-dd') >= FORMAT((CONVERT(smalldatetime,'2012-05-01',111)),'yyyy-MM-01') 
    AND FORMAT((CONVERT(smalldatetime,a.BillDate,111)),'yyyy-MM-dd') <= FORMAT((CONVERT(smalldatetime,eomonth('2012-05-01'),111)),'yyyy-MM-dd') 
and a.SpecialisationCode!=0 
and a.Specialisation NOT IN (' ') 
GROUP BY a.SpecialisationCode,a.Specialisation)MTD 

ON YTD.SpecialisationCode=MTD.SpecialisationCode 


LEFT OUTER JOIN 

(select 
a.SpecialisationCode, 
a.Specialisation, 
COALESCE(SUM(a.DoctorFee),0)Revenue_Today, 
SUM(a.Amount1)Amount1_Today, 
SUM(a.Amount2)Amount2_Today, 
SUM(a.Amount3)Amount3_Today, 
SUM(a.Amount4)Amount4_Today, 
SUM(a.Amount5)Amount5_Today 
from tbl_doctor a 
where FORMAT((CONVERT(smalldatetime,a.BillDate,111)),'yyyy-MM-dd') = '2012-05-01' 
and a.SpecialisationCode!=0 
and a.Specialisation NOT IN (' ') 
GROUP BY a.SpecialisationCode,a.Specialisation)Today 
ON YTD.SpecialisationCode=Today.SpecialisationCode) z 
order by z.Specialisation 

ответ

1

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

Я так долго не использовал SQL Server, поэтому я точно не понимаю логику даты, но, как я понимаю, вы вычисляете сумму в разные периоды времени, например, накопленные с начала года, поскольку начало месяца, и сегодняшняя сумма и т. д.

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

select a.SpecialisationCode 
     ,a.Specialisation 
     ,sum(case when a.BillDate = today then a.Amount1 end) as Amount1_Today 
     ,sum(case when a.BillDate between date 'first-day-in-month' and today then a.Amount1 end) as Amount1_MTD 
     ,sum(a.Amount1) as Amount1_YTD 
    from tbl_doctor 
where a.SpecialisationCode!=0 
    and a.Specialisation NOT IN (' ') 
    and a.BillDate between date 'first day in year' 
         and date 'today' 
group 
    by a.SpecialisationCode 
     ,a.Specialisation; 

Сообщите мне, если вы этого не сделаете!

Смежные вопросы