[英]Improving the performance of queries using SQL Server 2012?
I have a table which has 13,0000 records, but without indexing and I have written a query which has 4 LEFT OUTER JOINs. 我有一个包含13,0000条记录的表,但是没有索引,并且我编写了一个包含4个LEFT OUTER JOIN的查询。
The query is working fine without any issue. 该查询工作正常,没有任何问题。 My only concern is performance, it's taking 5-10 minutes to give the results.
我唯一关心的是性能,需要5到10分钟才能得出结果。 So my question is how can I improve the performance of the query?
所以我的问题是如何提高查询性能? My second question is do I need to add indexes?
我的第二个问题是我需要添加索引吗? If yes, which index should I add, cluster or non cluster?
如果是,我应该添加哪个索引,群集还是非群集?
My query is : 我的查询是 :
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
It looks to me that you can solve the entire query in one pass, by using conditional aggregation. 在我看来,您可以使用条件聚合一次性解决整个查询。
I haven't used SQL Server that much, so I don't exactly get the date logic, but as I understand you are calculating the amount over different time periods, like accumulated since the start of the year, since the start of the month, and todays amount etcetera. 我使用SQL Server的次数不多,所以我没有确切地了解日期逻辑,但是据我了解,您正在计算不同时间段的金额,例如自年初以来,本月初以来的累计量。 ,以及今天的金额等。
For such a query, you are anyway touching all records with a BillDate
between the start of the year and todays date. 对于这样的查询,无论如何,您要在年初和今天之间使用
BillDate
触摸所有记录。 You should be able to use a query similar to the below. 您应该能够使用与以下类似的查询。 The idea is to SUM the amount only if the BillDate is in the time period.
这个想法是仅在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;
Let me know if you don't get this to work! 让我知道您是否无法使用此功能!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.