来自查询执行计划的查询优化

时间:2019-03-13 11:53:08

标签: sql sql-server tsql sql-server-2016

除图像外,我没有找到任何合适的方式来显示查询计划,因此我添加了图像。在图像中,我得到了执行计划,并且我想减少全员加入成本

enter image description here

,如果有人建议我降低成本,那太好了for better query plan link

WITH cte AS
(
SELECT
 coalesce(fact_connect_hours.dimProviderId,fact_connect_hour_hum_shifts.dimProviderId,fact_connect_hour_clock_times.dimProviderId)
  as dimProviderId,
  coalesce(fact_connect_hours.dimScribeId,fact_connect_hour_hum_shifts.dimScribeId,fact_connect_hour_clock_times.dimScribeId)
  as dimScribeId
 ,coalesce(fact_connect_hours.dimDateId,fact_connect_hour_hum_shifts.dimDateId,fact_connect_hour_clock_times.dimDateId)
  as dimDateId
,factConnectHourId
,totalProviderLogTime
,providerFirstJoinTime
,providerLastEndTime
,scribeFirstLogin
,scribeLastLogout
,totalScribeLogTime
, totalScopeTime
, totalStreamTime
, firstScopeJoinTime
, lastScopeEndTime
, scopeLastActivityTime
, firstStreamJoinTime
, lastStreamEndTime
, streamLastActivityTime

,fact_connect_hour_hum_shifts.shiftStartTime
,fact_connect_hour_hum_shifts.shiftEndTime
,fact_connect_hour_hum_shifts.totalShiftTime
,fact_connect_hour_clock_times.ClockStartTimestamp
,fact_connect_hour_clock_times.ClockEndTimestamp
,fact_connect_hour_clock_times.totalClockTime
,fact_connect_hour_hum_shifts.shiftTitle
,fact_connect_hours.dimStatusId
,dim_status.status
FROM fact_connect_hours
INNER JOIN  dim_status on fact_connect_hours.dimStatusId=dim_status.dimStatusId
  full outer JOIN fact_connect_hour_hum_shifts
 ON ( fact_connect_hour_hum_shifts.dimDateId=fact_connect_hours.dimDateId 
  and fact_connect_hour_hum_shifts.dimProviderId=fact_connect_hours.dimProviderId 
  and fact_connect_hour_hum_shifts.dimScribeId=fact_connect_hours.dimScribeId)
full outer join fact_connect_hour_clock_times
    on (fact_connect_hours.dimDateId = fact_connect_hour_clock_times.dimDateId 
        and fact_connect_hours.dimProviderId= fact_connect_hour_clock_times.dimProviderId 
        and fact_connect_hours.dimScribeId = fact_connect_hour_clock_times.dimScribeId
       )
WHERE coalesce(fact_connect_hours.dimDateId,fact_connect_hour_hum_shifts.dimDateId,fact_connect_hour_clock_times.dimDateId)>=732
) SELECT cte.*
  ,dim_date.tranDate
,dim_date.tranMonth
,dim_date.tranMonthName
,dim_date.tranYear
,dim_date.tranWeek
,dim_scribe.scribeUId
,dim_scribe.scribeFirstname
,dim_scribe.scribeFullname
,dim_scribe.scribeLastname
,dim_scribe.location
,dim_scribe.partner
,dim_scribe.beta
,dim_scribe.currentStatus
,dim_scribe.scribeEmail
,dim_scribe.augmedixEmail
,dim_scribe.partner
,dim_provider.scribeManager
,dim_provider.clinicalAccountManagerName
,dim_provider.providerUId
,dim_provider.beta
,dim_provider.accountName
,dim_provider.accountGroup
,dim_provider.accountType
,dim_provider.goLiveDate
,dim_provider.siteName
,dim_provider.churnDate
,dim_provider.providerFullname
,dim_provider.providerEmail

  from cte

   INNER JOIN   dim_date on cte.dimDateId=dim_date.dimDateId
   inner JOIN  aug_bi_dw.dbo.dim_provider AS dim_provider on cte.dimProviderId=dim_provider.dimProviderId 
   inner join aug_bi_dw.dbo.dim_scribe AS dim_scribe on cte.dimScribeId=dim_scribe.dimScribeId 

where dim_date.dimDateId>=732

2 个答案:

答案 0 :(得分:2)

基于表名(dim *和事实*),我假设您正在对数据仓库模式进行排序报告。假设是这种情况,那么可能最好的改善性能的方法就是考虑使用Columnstore索引(以及启用Columnstores后隐式的批处理模式执行)。这些索引被高度压缩,并且通常会在IO绑定的工作负载上显着提高性能。事实表是通常的候选者,因为它们最大,通常不适合缓冲池。

SQL 2016及更高版本的所有版本均支持列存储,而在企业版中,列存储的运行速度更快(并行度更高,内部操作更快,如使用SIMD指令等)。请注意,它们不直接支持主键,因此这可能会影响您对表的布局。您可以创建键(在内部作为b树二级索引),因此如果使用主键,则会浪费一些空间。通常,事实表+列存储还使用分区来获得没有辅助索引的另一层过滤。

请考虑使用列存储替换事实表(也许在数据库的副本上进行实验),再次尝试查询。当您查看结果查询计划时,建议您还查看操作员是否以批处理模式运行。批处理模式运算符与行模式运算符不同。批处理模式针对现代CPU的体系结构进行了优化,以最大程度地减少进出CPU的内存流量。作为粗略的经验法则,列存储+批处理模式可能会造成10x-100x的差异。

答案 1 :(得分:0)

唯一可以帮助您的过滤器是“ where dim_date.dimDateId> = X” 并且这涉及到cte的联接,而cte字段由外部联接自身的3个表组成。为了获得最佳性能,我会选择告诉sql逐步执行操作,否则按原样执行最佳计划会很冒险:

  1. 在3个临时表上使用过滤器,在表fact_connect_hours,fact_connect_hour_hum_shifts和fact_connect_hour_clock_times上使用3条语句,并将结果(只是主键或所需的所有列)分成3个临时文件,例如#fact_connect_hours,#fact_connect_hour_hum_shifts和#fact_connect_hour_clock_times

  2. 按原样使用该语句,但替换为临时文件;如果临时文件只有PK,请使用临时文件联接真实表

  3. 将索引(如果尚不存在)添加到列fact_connect_hours.dimDateId,fact_connect_hour_hum_shifts.dimDateId和fact_connect_hour_clock_times.dimDateId

这样,您可以确保在最简单的步骤中直接过滤所需的内容,然后复杂的查询将在预设的行数下工作,因此可以保证性能,因为实际上对几行应用了非常好还是很差的计划不重要。

详细信息:请注意'INNER JOIN dim_status'-如果没有FK约束,则基数估计器可能会因为无法理解表之间的关系而错过估计的返回行。

我也看到了优化的尝试,因为过滤器已经上升到cte中。这与我在较小限制下提出的计划类似。使用我的计划将强制对核心根源进行行搜索。