2015-10-19 71 views
1

我有这个很老的SLOW查询,我试图优化,但我不确定我可以做任何事情,但在涉及WHERE,JOIN和ORDER BY的列中添加更多索引。优化查询与添加索引

查询:

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 

执行计划: execution plan

说实话,我不知道如何处理这个查询做。

我应该在涉及WHERE JOIN和ORDER BY的所有列上添加单个非聚簇索引吗?

有这些表多项指标,但我不知道他们是否有帮助在此查询:

enter image description here

+0

你是否以某种方式自动创建基于数据库调优顾问结果的索引?或者你怎么能有这么多重复的索引... –

+0

我不知道。我试图清理混乱:) – Angelina

回答

1

看着这个SQL,我真的没有看到任何明确的标准,也就是被用来获取行。它看起来只是排除了许多具有不同标准的行。我的猜测是,票据通常以大部分行的状态结束,并且这些行未包含在结果中?

这样做的问题是,它并没有任何明确的标准,它有很多不同的规则,所以这就是为什么它最终为所有的聚合索引扫描+键查找行。扫描从jobinfo开始,但我不确定它是否会从jobticket开始有所作为。

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

该查询看起来相当复杂,所以我的猜测是你不能创建一个包含这些数据的索引视图。这可能有助于假设这个查询经常执行并且数据没有太多变化(并且维护大量索引的开销将被删除),但这可能是不可能的。

另一个想法是调查规则何时可以排除行,并有可能有更明确的规则,因此可以索引,也许通过在表中添加一个持久的计算列。

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

ps。除非在特殊情况下,否则我个人不推荐使用NOLOCK,因为它会导致难以解决的问题,例如多次读取相同的数据或完全跳过行。

+1

对于索引视图,如果您可以创建一个连接jobinfo和jobticket的连接,它可能会有所帮助,因为我的猜测是加入这些表+关键查找是缓慢的原因。 –

+1

如果索引视图不起作用,肯定有些过滤索引会有所帮助。正如你所提到的,这里的主要难点在于清楚地隔离了过滤条件。乐观的过滤方式可能会产生比悲观方式更快的响应。也许像将JobInfo过滤器移动到Join本身那样简单,而不是在哪里可能有帮助。 –

+0

@BradD将JobInfo过滤器移动到JOIN中意味着什么? – Angelina

1

一个简单的解决方法是在job_info和tblConsolidatedBilling覆盖索引,因为在那里的关键查找花费了大量的时间。这应该给整数倍加速。如果这还不够,我们需要进一步调查。

+0

应该为job_info和tblConsolidatedBilling表中的每个列创建索引吗? – Angelina

+0

每个表都应该接收一个包含此查询所需的所有列的索引。 – usr