2017-03-20 84 views
0

我在同一張表上有2個查詢,並且我期望有類似的性能,但我仍然得到了巨大的差異 - 30秒與1秒。SQL Server:針對類似查詢的不同執行計劃和性能

查詢1:用戶數爲當月

SELECT datepart(year,getdate()) as TheYear, 
     DATEPART(month, GETDATE()) AS TheMonth, 
     COUNT(DISTINCT Username) AS TheUsers 
FROM dbo.[AP-Data] 
WHERE datepart(year,RequestDate) = datepart(year,getdate()) 
    AND datepart(month,RequestDate) = datepart(month,getdate()) 

問題2:用戶數爲本週

SELECT datepart(year,getdate()) as TheYear, 
     DATEPART(week, GETDATE()) AS TheWeek, 
     COUNT(DISTINCT Username) AS TheUsers 
FROM dbo.[AP-Data] 
WHERE datepart(year,RequestDate) = datepart(year,getdate()) 
    AND datepart(week,RequestDate) = datepart(week,getdate()) 

表有〜350萬點的記錄,它是由RequestDate索引。該月的計數正在進行全表掃描,因此需要30秒,本週的計數是在1秒內完成RID查找 - 這些信息來自執行計劃。

任何想法爲什麼區別?

+0

做一些研究,如果有東西是SARG能。如果你在join或where子句的列上使用函數,通常不能利用它的索引。 – dfundako

+1

你不應該在'WHERE'上使用'DATEPART(something,RequestDate)'。嘗試重寫它們以使用類似於:'WHERE RequestDate> = CONVERT(VARCHAR(6),GETDATE(),112)+'01''或類似 – Lamak

+0

謝謝,我試過了,我也得到了奇怪的結果: 'SELECT COUNT(DISTINCT Shortname)AS TheUsers FROM dbo。[AP-Data] WHERE RequestDate>'2017-03-01' 運行在第二個。但是 SELECT COUNT(DISTINCT Shortname)AS TheUsers FROM dbo。[AP-Data] WHERE RequestDate> CONCAT(datepart(year,getdate()),' - 0',datepart(month,getdate()),' - 01' ) 在30秒內運行。 –

回答

3

如何嘗試這些查詢?

SELECT year(getdate()) as TheYear, month(GETDATE()) AS TheMonth, 
     COUNT(DISTINCT Username) AS TheUsers 
FROM dbo.[AP-Data] 
WHERE RequestDate >= dateadd(month, datediff(month, 0, getdate()), 0); 

和:

SELECT year(getdate()) as TheYear, month(GETDATE()) AS TheMonth, 
     COUNT(DISTINCT Username) AS TheUsers 
FROM dbo.[AP-Data] 
WHERE RequestDate >= dateadd(week, datediff(week, 0, getdate()), 0); 

使用上的列函數通常防止編譯器使用索引。以上假設您沒有將來的請求日期。

+0

他們都在1秒內工作。這僅僅是我在最初的查詢中工作得很好,我仍然有興趣瞭解差異來自哪裏。 –

+0

也嘗試獲取前一個月的COUNT,它不起作用(快): 'SELECT year(getdate())as TheYear,month(GETDATE())AS TheMonth, COUNT(DISTINCT Username)AS TheUsers (月,0,getdate()) - 請求日期