2013-12-09 36 views
1

我已經從這個網站獲益很長一段時間了。這是我在網站上的第一個問題。這是關於性能調整報告查詢。在這裏。 1.調整Select語句以獲得更快的結果

SELECT Count(b1.primkey) 
from tableA b1 --WITH (NOLOCK) 
join tableA b2 --WITH (NOLOCK) 
on b1.email = b2.email 
and DateDiff(day, b2.BookedDate , b1.BookedDate) > 1 

tableA有大約700萬行。電子郵件是varchar(100)字段。 Bookeddate是一個日期時間字段。 primkey是一個int的主鍵列。

我寫這個查詢的目的是爲了找出具有相同電子郵件ID的計數條目,但遲到一天。此查詢大約需要45分鐘才能運行。我真的想減少執行所需的時間。

由於這是報告,我妄圖使用--WITH (NOLOCK)選項來提高閱讀時間。我在tableA上有一個列存儲索引,我知道它正在被SQL優化器使用 - 可以在執行計劃中看到。我正在使用SQL Server 2012.

  1. 有人可以告訴我,在這種情況下,會更好嗎?在電子郵件上使用非聚簇索引或在tableA上使用非聚簇列索引?

請幫幫我。

+1

請發佈執行計劃。如果您還無法在此處上傳圖片,則可以在外部託管它。或者將.sqlplan文件上傳到某處。有多少個不同的電子郵件地址?考慮一下:如果2013-01-01日期的某個電子郵件有10條記錄,2013-01-02日期的同一電子郵件有10條記錄,那麼這將記錄爲100(而不是10)。你知道嗎? – usr

回答

0

您所查詢的是相對複雜的。你基本上是加入了兩個表,每個表有700萬條記錄,這些記錄不是唯一的。

如何下面的查詢代替:

select Email 
from TableA 
group by Email 
having MAX(BookedDate) > MIN(BookedDate) + 1 

另外,還要確保你有電子郵件和BookedDate的索引。

希望這會有所幫助。

+0

這是一個很好的。謝謝。我會試試看 – user3082259

0

你有3個選擇這裏:

  1. 至少對於較大的表創建於email場聚集索引。需要在其他領域
  2. 郵件轉移到另一個表,並存儲電子郵件ID在表A和表B 但我想有這些表上運行的其他查詢,並 聚集索引;加入對INT領域會比在VARCHAR 領域快得多
  3. 與包含的列上創建電子郵件字段的索引BookedDate(無 需要包括primkey,你可以指望另一個字段,或COUNT(*)代碼:create index idx_email on TableA include(BoodedDate)

我覺得第三個選擇是你應該去的,沒有太多的工作要做,並且會有很大的性能提升,唯一的問題是varchar字段上的索引會佔用很多空間,影響插入/更新操作;但是你說這是一個報告數據庫,所以我認爲你可以允許。

+1

700萬行表如何導致45分鐘的運行時間?即使是堆表應該更快。還有一件事我們還不知道。 SQL Server甚至可以在查詢執行期間構建臨時索引。 – usr

+0

@us同意,但問題在於調整select語句,我們可以立即回答。 –

-1

希望你的查詢ou輸入是正確的。當你使用500強時,它會給你正確的記錄。

當您使用任一條件時需要多少次。

我也希望您知道非聚集列存儲索引。 它僅在Readonly表中使用,這意味着您無法在該表上插入/更新/刪除。

如果沒有,那麼只讀您可以創建電子郵件和日期列的非聚集索引都

相關問題