Tsql 从视图中选择所需时间超过30秒;会议记录

Tsql 从视图中选择所需时间超过30秒;会议记录,tsql,sql-server-2016,query-performance,query-tuning,Tsql,Sql Server 2016,Query Performance,Query Tuning,我正在努力使这个视图足够快,以便在合理的时间内获取结果集,目前这需要超过30分钟的时间,并行运行,并随着cpu时间的增加而带来各种痛苦。我已经确定了有问题的查询,但我无法找到一种方法来缩短执行时间,即重新编写查询,或者在需要时添加适当的索引。在这两个表中,我们已经在client_id上有聚集索引,在hash_key列上有非聚集索引。此外,这些各自的联接表有近2.38亿条来自工作单的记录,以及来自s_检查表的总计287011570条记录 select wo.client_id,

我正在努力使这个视图足够快,以便在合理的时间内获取结果集,目前这需要超过30分钟的时间,并行运行,并随着cpu时间的增加而带来各种痛苦。我已经确定了有问题的查询,但我无法找到一种方法来缩短执行时间,即重新编写查询,或者在需要时添加适当的索引。在这两个表中,我们已经在client_id上有聚集索引,在hash_key列上有非聚集索引。此外,这些各自的联接表有近2.38亿条来自工作单的记录,以及来自s_检查表的总计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)
下面是估计的执行计划,因为这需要很长时间,所以我无法提供实际的执行计划


任何帮助都将不胜感激。

也许这将有助于保持您的业务,因为行号()是问题所在。尝试:

;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;

计算标量是查询成本的59%。 我猜是这样的: (按si.work\u orders\u hash\u key分区,si.inspection\u id按si.dss\u version desc排序)rnk上的行号() 估计有159014000000行!
重击此行(返回行号需要大量工作),然后再次运行它。

除非我读错了,否则返回的估计行数看起来相差很远。您希望在结果集中包含多少行?开发人员希望在视图中显示前1000行,但此查询本身正在对数百万条记录执行联接。如果添加前1000行,性能是否会提高?你从来没有回答过这个问题-你希望在上面的查询中有多少行?前1000行是整个视图的…下面的代码只是它的一个子集,但这一部分才是真正的罪魁祸首。此外,不,这并不能提高性能。不幸的是,我没有关于该查询将产生多少行的答案,因为查询本身需要30分钟以上的时间,并且导致问题,我必须在这段时间内停止查询。排名前1000位的顺序是什么?我将尝试一下……你是对的,行数()是问题的根源。然而,现在的问题是,它为什么存在,我们真的需要它吗。另外,事实上,我们可以替换这个东西……它会影响代码逻辑吗?如果需要行号,可以尝试将逻辑移到from子句。它应该只运行一次,而不是针对结果集中的每一行。您能否提供如何使用from子句中逻辑的实际实现?让我试试。