如何优化具有多个相似条件的查询

时间:2018-03-28 07:17:00

标签: sql sql-server query-optimization

我已经查询了我从多个选择语句填充临时表的问题,这些语句使用了多个类似条件,但我无法优化查询。

if object_id('tempdb..#tempTable') is not null

    drop table #tempTable

select totalProcessed=(select  COUNT(*) as totalProcessed 
from DetailItem di
inner join DownloadFile df 
on di.DownloadFileID = df.DownLoadID
where 
(CONVERT(date, di.CompletionTime)) = '2018-01-31' and
di.DetailItemName<>'99999999' 
and df.CompanyID = 164 
and (df.filename like '%OA73030%'  or df.filename like '%OA73035%'
or df.FileName like '%OA77030%' or df.filename like '%OA77035%')),

totalErrored=(select  COUNT(*) as totalErrored 
from DetailItem di
inner join DownloadFile df 
on di.DownloadFileID = df.DownLoadID
where 
(di.CompletionDetail  like '%Not found%'or di.CompletionDetail  like '%error%')  and 
CONVERT(date, di.CompletionTime) ='2018-01-31' 
and di.DetailItemName<>'99999999' 
and df.CompanyID = 164 
and (df.FileName like '%OA73030%' or df.filename like '%OA73035%'
or df.FileName like '%OA77030%' or df.filename like '%OA77035%')),

totalSuccess=(select  COUNT(*) as totalSuccess 
from DetailItem di
inner join DownloadFile df 
on di.DownloadFileID = df.DownLoadID
where 
(di.CompletionDetail not like '%error%' and di.CompletionDetail not like '%Not Found%') and 
CONVERT(date, di.CompletionTime) ='2018-01-31' 
and di.DetailItemName<>'99999999' 
and df.CompanyID = 164
and (df.FileName like '%OA73030%' or df.filename like '%OA73035%'
or df.FileName like '%OA77030%' or df.filename like '%OA77035%')) into #tempTable
select totalProcessed, totalErrored, totalSuccess,cast(round(((totalSuccess*100.0)/totalProcessed),2) as decimal(5,2)) as '%ProcessedSuccessfully',
(totalProcessed-totalSuccess)as 'TotalRe-Processed(2ndBD)',0 as 'TotalSuccessfullyProcessedOutOfRe-order(3rdBD)',0 as 'TotalSLAMissed' 
from #tempTable

3 个答案:

答案 0 :(得分:2)

我认为搜索值是动态的,无法预测要选择的内容。然后,你不能用以下结构做很多事情:

WHERE df.filename like '%OA73030%'  or df.filename like '%OA73035%'
or df.FileName like '%OA77030%' or df.filename like '%OA77035%'

由于无法将其重写为:

WHERE df.filename like IN ('%OA73030%','%OA73035%','%OA77030%','%OA77035%')

但是,您可以通过以下方式优化查询的整个逻辑:

SELECT COUNT(*) AS totalProcessed
,       COUNT(CASE WHEN    di.CompletionDetail LIKE '%Not found%' OR di.CompletionDetail LIKE '%error%'  THEN 1 END) AS totalErrored
,       COUNT(CASE WHEN    di.CompletionDetail NOT LIKE '%error%' AND di.CompletionDetail NOT LIKE '%Not Found%'  THEN 1 END) AS totalErrored
,       COUNT(CASE WHEN    di.CompletionDetail NOT LIKE '%error%' AND di.CompletionDetail NOT LIKE '%Not Found%'  THEN 1 END) AS totalSuccess
FROM   DetailItem di
       INNER JOIN DownloadFile df ON di.DownloadFileID = df.DownLoadID
WHERE  di.CompletionTime between '2018-01-31' AND '2018-01-31 23:59:59'
       AND di.DetailItemName <> '99999999'
       AND df.CompanyID = 164
       AND (   df.filename LIKE '%OA73030%'
               OR df.filename LIKE '%OA73035%'
               OR df.FileName LIKE '%OA77030%'
               OR df.filename LIKE '%OA77035%' );

在这种情况下,数据引擎只需搜索一次所有聚合数据而不是四次。

接下来,你修剪时间的方法不是SARGable:

( CONVERT(DATE, di.CompletionTime)) = '2018-01-31'

并且必须重写为:

di.CompletionTime between '2018-01-31' AND '2018-01-31 23:59:59'

否则将不会使用CompletionTime上的可能索引

答案 1 :(得分:0)

你应该确保DownloadFile.CompanyID上有一个索引并确保你的查询通过检查执行计划(如果它不使用索引然后使用提示)来使用它,除了没有你可以用这样的查询做很多事情。

答案 2 :(得分:0)

你可以像下面的条件一样使用正则表达式

df.filename like '%OA7[37]03[05]%'  

see live demo