2015-10-19 64 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