从视图中进行选择需要花费超过30分钟的时间

时间:2019-03-01 22:55:16

标签: tsql sql-server-2016 query-performance query-tuning

我正在努力使此视图足够快,以在合理的时间内获取结果集,而这目前需要30多个分钟的时间,并行运行并会因CPU时间的增加而引起各种痛苦。我已经确定了问题查询,但是我找不到解决方法,可以通过重新编写查询或在需要时添加适当的索引来缩短执行时间。在两个表中,我们已经在client_id上具有聚簇索引,在hash_key列上具有非聚簇索引。此外,这些连接表分别包含来自work_orders的约2.38亿条记录和s_inspections表中的287011570条记录。

select
    wo.client_id, 
    wo.work_orders_hash_key,
    wo.work_order_number, 
    wo.work_order_id, 
    si.inspection_id, 
    si.inspection_name,
    si.inspection_detail, 
    si.master_inspection_id, 
    si.master_inspection_detail, 
    si.status_id, 
    si.exception, 
    si.inspection_order, 
    si.comment,
    si.[procedure_id],
    si.[flag_id],
    si.[asset_id],
    si.[asset_name],
    si.[inspection_status],
    si.[is_removed],
    si.[response],
    row_number() over(partition by si.work_orders_hash_key, si.inspection_id order by si.dss_version desc) rnk
from
    datavault.dbo.h_work_orders wo with (readuncommitted) 
    join datavault.dbo.s_inspections si with (readuncommitted) on wo.client_id = si.client_id and wo.work_orders_hash_key = si.work_orders_hash_key 
where
    wo.client_id in (7700876368663, 8800387996408)

下面是估计的执行计划,因为它花了很长时间,所以我无法提供实际的执行计划。

https://www.brentozar.com/pastetheplan/?id=ryLzvNwUN

任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:1)

您的计算标量是查询成本的59%。 我想这是这行: row_number()over(按si.work_orders_hash_key进行分区,si.inspection_id按si.dss_version desc进行排序) 估计159014000000000行! 重击此行(需要执行很多工作才能返回行号)并再次运行。

答案 1 :(得分:0)

也许这将使您继续经营下去,因为row_number()是问题所在。尝试:

;with x as (
select
    wo.client_id, 
    wo.work_orders_hash_key,
    wo.work_order_number, 
    wo.work_order_id, 
    si.inspection_id, 
    si.inspection_name,
    si.inspection_detail, 
    si.master_inspection_id, 
    si.master_inspection_detail, 
    si.status_id, 
    si.exception, 
    si.inspection_order, 
    si.comment,
    si.[procedure_id],
    si.[flag_id],
    si.[asset_id],
    si.[asset_name],
    si.[inspection_status],
    si.[is_removed],
    si.[response],
    si.dss_version
from
    datavault.dbo.h_work_orders wo with (readuncommitted) 
    join datavault.dbo.s_inspections si with (readuncommitted) on wo.client_id = si.client_id and wo.work_orders_hash_key = si.work_orders_hash_key 
where
    wo.client_id in (7700876368663, 8800387996408)
    )
select 
    x.client_id, 
    x.work_orders_hash_key,
    x.work_order_number, 
    x.work_order_id, 
    x.inspection_id, 
    x.inspection_name,
    x.inspection_detail, 
    x.master_inspection_id, 
    x.master_inspection_detail, 
    x.status_id, 
    x.exception, 
    x.inspection_order, 
    x.comment,
    x.[procedure_id],
    x.[flag_id],
    x.[asset_id],
    x.[asset_name],
    x.[inspection_status],
    x.[is_removed],
    x.[response],
    row_number() over(partition by x.work_orders_hash_key, x.inspection_id order by x.dss_version desc) rnk
from x;