【发布时间】:2018-10-03 18:41:33
【问题描述】:
我有一组表,我要加入这些表以创建一个记录集,然后在该集上运行一个额外的选择来检索一些记录。 代码中的查询在视图中用作 CTE。
仅检查子查询时,它的运行速度非常快,例如 0.01 - 0.02 秒。 如果使用临时表来检索记录,这同样适用。因为我打算在视图中使用它,所以临时表解决方案超出了范围。常规查询运行时间为 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;
----该查询正在视图中使用,因此需要解决子查询问题并减少运行时间。
【问题讨论】:
-
我会从解释选择开始看。您可以在同一个会话下进行几个查询,创建一个临时表,执行 ibsert 选择并使用结果
-
有关查询优化的问题应包括表结构(如适用)以及示例数据。但是,在查看您的查询后,一些事情立即跳出来。
dbo.Abc中有什么内容?您只使用FullDate列对dt.cde进行左连接。对于来自dbo.Abc的值,您没有WHERE条件,因此我可以看到这可能会返回大量与dt.cde中的任何内容都不匹配的FullDate值,从而导致将大量NULL 数据连接在一起. -
@GuyLouzon 我有一个运行良好但对我没有用的临时表查询,因为我无法在创建视图语句中使用的 CTE 中使用它。 CREATE 视图 [dbo].[vw_cost] 与 cte_xyz 一样(上述查询)。
-
简化,简化,简化。从一个简单的查询开始,然后添加新表以查看性能问题出在哪里。然后修复它。
-
@PandoraBox 然后我会尝试使用连接而不是子查询,我会尝试自己编写,但是您的查询很复杂...
标签: sql sql-server tsql ssms-2014