[英]SQL Sub-query run's very fast individually, but when used in select is very slow
I have a set of tables which i am joining to create a record set and then run a additional select on the set to retrieve some records. 我有一组表,我将这些表加入以创建记录集,然后在该集上运行其他选择以检索一些记录。 The query in the code is being used in a view as a CTE. 代码中的查询在视图中用作CTE。
While checking the sub-query only it runs extremely faster like 0.01 - 0.02 secs. 仅检查子查询时,它的运行速度非常快,如0.01-0.02秒。 same applies for if a temp table is used to retrieve the records. 如果使用临时表检索记录,则同样适用。 As I am planning to use it inside a view the temp table solution is Out of scope. 当我计划在视图中使用它时,临时表解决方案超出了范围。 The regular query runs from 37-50 mins instead. 常规查询的运行时间为37-50分钟。
SELECT
CallDate
,MediaChannel
,SubCategory
,Vendor
,BusinessVertical
,SUM(NumberOfLeads) AS NumberOfLeads
,CASE
WHEN SUM([CostPerLead]) <> 0
THEN SUM([CostPerLead])
ELSE NULL
END AS Cost
,[CostPerLead]
,SourceName
,ParentLeadSource
,IsBillable
,dvce_type
FROM (
SELECT [PhoneLabel]
,[DialogTechCallId] = cd.DialogTechCallId
,[LeadId] = c.LeadId
,[CostPerLead] = CAST(cpl.cost AS INT)
,[SourceName] = bt.LeadCompany
,[ParentLeadSource] = ftlc.fruit
,[DialogTechPhoneNumber] = cd.CalledNumber
,[CallDate] = CAST(cd.[CallDateTime] AS DATE)
,[CallType] = cd.CallType
,[TalkTime] = cd.[TalkTimeMinutes]
,[TalkTimeSeconds] = CASE
WHEN ISNUMERIC(cd.[TalkTimeMinutes]) = 1
THEN CAST(cd.[TalkTimeMinutes] AS DECIMAL(10, 2)) * 60
ELSE 0
END
,[TimeToQualify] = bt.Billabletime
,[IsBillable] = CASE
WHEN ISNUMERIC(cd.[TalkTimeMinutes]) = 1
THEN CASE
WHEN CAST(cd.[TalkTimeMinutes] AS DECIMAL(10, 2)) * 60
>= CAST(bt.Billabletime AS INT)
THEN 1
WHEN bt.Billabletime = 900
THEN 1
ELSE 0
END
ELSE 0
END
,[MediaChannel] = ftlc.channel2
,[SubCategory] = ftlc.sub
,[Vendor] = ftlc.vendor
,[BusinessVertical] = ftlc.business_vertical
,[NumberOfLeads] = 1
,[dvce_type] = ftlc.dvce_type
FROM [dbo].[Abc] d WITH (NOLOCK)
LEFT JOIN [dt].[cde] cd WITH (NOLOCK) ON d.FullDate =
CAST(cd.CallDateTime AS DATE)
LEFT JOIN [dt].[efg] c WITH (NOLOCK) ON cd.DialogtechCallId =
c.DialogTechCallid
INNER JOIN [dt].[hij] m WITH (NOLOCK) ON cd.CallerId =
m.DialogTechPhoneNumber
INNER JOIN [dt].[klm] bt WITH (NOLOCK) ON m.LeadSourceInfoId =
bt.LeadSourceId AND cd.[CallDateTime] BETWEEN bt.[StartDateTime]
AND ISNULL(bt.[EndDateTime], GETDATE())
INNER JOIN [dbo].[jkl] ftlc WITH (NOLOCK) ON bt.ParentLeadSource =
ftlc.fruit
INNER JOIN dbo.xyz cpl WITH (NOLOCK) ON ftlc.lead_company =
cpl.lead_company AND cd.[CallDateTime] >= cpl.[start_date]
AND cd.[CallDateTime] <= ISNULL(cpl.[end_date], GETDATE())
WHERE CAST(cd.[CallDateTime] AS DATE) >= '2018-08-01'
AND CASE WHEN ISNUMERIC(cd.[TalkTimeMinutes]) = 1
THEN CASE
WHEN CAST(cd.[TalkTimeMinutes] AS DECIMAL(10, 2)) * 60
>= CAST(bt.Billabletime AS INT)
THEN 1
WHEN bt.Billabletime = 900
THEN 1
ELSE 0
END
ELSE 0
END = 1
) sub
GROUP BY
CallDate
,MediaChannel
,SubCategory
,Vendor
,BusinessVertical
,SourceName
,ParentLeadSource
,IsBillable
,dvce_type
,CostPerLead;
----The query is being used in view so need to tackle the sub query issue and reduce the running time. ----在视图中使用了查询,因此需要解决子查询问题并减少运行时间。
You have some data in your subquery that is not used in your outer query. 您的子查询中有一些未在外部查询中使用的数据。 Some of your joins could also introduce joining NULL values to NULL values, which will kill your performance. 您的某些联接还可能将NULL值联接到NULL值,这会降低性能。
Without knowing your table structures or functions, nor any of the actual data, I came up with the following simplified version of your query. 在不知道您的表结构或函数或任何实际数据的情况下,我想出了以下简化的查询版本。 It removes unused columns from the subquery, a subsequently-useless join, simplified CASE
statements, and the removal of CostPerLead
from the main query, since you're aggregating this. 它会从子查询中删除未使用的列,随后无用的CostPerLead
,简化的CASE
语句以及从主查询中删除CostPerLead
,因为您正在对此进行汇总。
SELECT
CallDate
,MediaChannel
,SubCategory
,Vendor
,BusinessVertical
,NumberOfLeads = COUNT(*)
,Cost = NULLIF(SUM(CostPerLead), 0)
,SourceName
,ParentLeadSource
,IsBillable
,dvce_type
FROM
(
SELECT
CallDate = CAST(cd.CallDateTime AS DATE)
,MediaChannel = ftlc.channel2
,SubCategory = ftlc.sub
,Vendor = ftlc.vendor
,BusinessVertical = ftlc.business_vertical
,CostPerLead = CAST(cpl.cost AS INT)
,SourceName = bt.LeadCompany
,ParentLeadSource = ftlc.fruit
,IsBillable = CASE WHEN ISNUMERIC(cd.TalkTimeMinutes) = 1
AND (
CAST(cd.TalkTimeMinutes AS DECIMAL(10, 2)) * 60 >= CAST(bt.Billabletime AS INT)
OR
bt.Billabletime = 900
)
THEN 1
ELSE 0
END
,dvce_type = ftlc.dvce_type
FROM dbo.Abc d WITH (NOLOCK)
INNER JOIN dt.cde cd WITH (NOLOCK) ON d.FullDate = CAST(cd.CallDateTime AS DATE)
INNER JOIN dt.hij m WITH (NOLOCK) ON cd.CallerId = m.DialogTechPhoneNumber
INNER JOIN dt.klm bt WITH (NOLOCK) ON m.LeadSourceInfoId = bt.LeadSourceId
AND cd.CallDateTime BETWEEN bt.StartDateTime AND ISNULL(bt.EndDateTime, GETDATE())
INNER JOIN dbo.jkl ftlc WITH (NOLOCK) ON bt.ParentLeadSource = ftlc.fruit
INNER JOIN dbo.xyz cpl WITH (NOLOCK) ON ftlc.lead_company = cpl.lead_company
AND cd.CallDateTime BETWEEN cpl.start_date AND ISNULL(cpl.end_date, GETDATE())
WHERE
d.FullDate >= '2018-08-01'
AND (
ISNUMERIC(cd.TalkTimeMinutes) = 1
AND (
CAST(cd.TalkTimeMinutes AS DECIMAL(10, 2)) * 60 >= CAST(bt.Billabletime AS INT)
OR
bt.Billabletime = 900
)
)
) sub
GROUP BY
CallDate
,MediaChannel
,SubCategory
,Vendor
,BusinessVertical
,SourceName
,ParentLeadSource
,IsBillable
,dvce_type;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.