Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 优化查询与添加索引_Sql Server_Query Optimization_Sql Execution Plan - Fatal编程技术网

Sql server 优化查询与添加索引

Sql server 优化查询与添加索引,sql-server,query-optimization,sql-execution-plan,Sql Server,Query Optimization,Sql Execution Plan,我有一个非常古老且缓慢的查询,我正在尝试优化它,但我不确定我能对它做些什么,而是在WHERE、JOIN和orderby中涉及的列上添加更多索引 查询: SELECT TOP 400 jobticket.jobnumber, jobticket.typeform, jobticket.filename, jobticket.req_number, jobticket.reqd_del_date, jobticket.point_of_contact, jobticket.status, jobti

我有一个非常古老且缓慢的查询,我正在尝试优化它,但我不确定我能对它做些什么,而是在WHERE、JOIN和orderby中涉及的列上添加更多索引

查询:

SELECT TOP 400 jobticket.jobnumber, jobticket.typeform, jobticket.filename, jobticket.req_number, jobticket.reqd_del_date, jobticket.point_of_contact, jobticket.status, jobticket.DapsDate, jobticket.elpod, job_info.IDOrderMaskedStatus, job_info.job_status, job_info.SalesID, job_info.location, job_info.TOMetadataID 
FROM jobticket WITH (NOLOCK) 
INNER JOIN job_info WITH (NOLOCK) ON job_info.jobnumber = jobticket.jobnumber 
WHERE  
(
    NOT(
        (jobticket.status = 'Complete' OR jobticket.status = 'Completed') 
         and (job_info.job_status = 'Actualized' OR job_info.job_status = '' 
              OR job_info.job_status = 'Actualized Credit Billed' 
              OR job_info.job_status = 'DWAS Actualized' OR job_info.job_status = 'DWAS Actualized Credit Billed'
             )
        )  
    or 
    ((SELECT COUNT(job_status) AS Expr1 FROM tblConsolidatedBilling AS tblConsolidatedBilling_1 WITH (NOLOCK)  
      WHERE  (job_status <> 'Actualized' 
      AND  job_status <> 'Actualized Credit Billed') 
      AND (master_jobnumber = jobticket.jobnumber)) > 0) 
) 
and (jobticket.status != 'Waiting Approval' or (jobticket.status = 'Waiting Approval' and jobticket.DPGType is null))  
and jobticket.typeform <> 'todpg'  
and ((job_info.isHidden <> 1 or job_info.isHidden is null) and job_info.isInConcurrentRelease is null)  
and job_info.deleted != '1' 
and jobticket.status != 'New Job'  
and jobticket.status != 'PRFYCLSFD'  

ORDER BY 
job_info.expediencyLevel DESC, 
jobticket.jobnumber DESC
执行计划:

老实说,我不知道该怎么处理这个问题

我是否应该在WHERE JOIN和ORDER BY中涉及的所有列上添加单独的非聚集索引

这些表上有许多索引,但我不确定它们是否有助于此查询:


看看这个SQL,我真的看不到任何用于获取行的明确标准。看起来它只是排除了许多具有不同条件的行。我的猜测是,票证通常会在大多数行都是的状态下结束,而这些行不包括在结果中

问题是,它实际上没有任何明确的标准,而且有很多不同的规则,因此它最终对所有行执行聚集索引扫描+键查找。扫描从jobinfo开始,但我不确定从jobticket开始是否会有任何区别

删除大多数索引可能是一个很好的开始,但它根本不会加快选择的速度

查询看起来相当复杂,所以我猜您无法创建包含此数据的索引视图。这可能有助于假设经常执行此查询,并且数据没有发生太多更改,而且维护大量索引的开销也会被消除,但这可能是不可能的

另一个想法是在可以排除行时调查规则,是否有可能有更明确的规则,以便可以对其进行索引,可能是通过向表中添加一个持久化的计算列

您没有提到这实际需要多长时间,以及表中有多少行,所以基本上一切都只是猜测。在问题中加入更多数据+统计io输出可能会有所帮助


另外,我个人不建议使用NOLOCK,除非是在非常特殊的情况下,因为它会导致非常难以解决的问题,就像多次读取相同的数据或完全跳过行一样。

一个简单的解决方法是在job_info和tblConsolidatedBilling上建立索引,因为在那里花费了大量的时间进行关键查找。这将提供一个整数因子加速。如果这还不够,我们需要进一步调查。

您是否根据数据库优化顾问的结果自动创建索引?或者你怎么会有这么多重复的索引…我不知道。我正在尝试清理混乱:对于索引视图,如果您可以创建一个连接jobinfo和jobticket的视图,它甚至可能会有所帮助,因为我的猜测是,连接这些表+键查找是速度缓慢的原因。如果索引视图不起作用,一些过滤的索引肯定会有所帮助。正如您所提到的,这里的主要难点是过滤条件的明确隔离。乐观的方法可能比悲观的方法产生更快的响应。也许简单到将JobInfo筛选器移动到联接本身,而不是where条件可能会有所帮助。@BradD将JobInfo筛选器移动到联接中是什么意思?@Angelina-我猜JobInfo表在垂直方向上相当大。您的查询是结构化的,因此您可以返回整个JobInfo表,然后通过where过滤器对其进行缩减。所以不要说选择…从…加入。。。其中…作业信息/票证标准执行此操作;选择从…JOIN JobInfo Criteria…何处JobTicket Criteria我应该为job_info和tblConsolidatedBilling表中的每一列创建索引?每个表应该接收一个索引,其中包含此查询所需的所有列。