亞歷克斯,
可以有許多原因的大量閱讀,而且我相信,@喬納森的回答將幫助,或者掩蓋了問題,現在。獲得大量讀取的原因將是因爲您缺少一些關鍵索引,並且/或者您的表統計信息不是最新的,或者它已關閉。
現在在像這樣的大表上進行性能調整可能會很複雜,如果它被許多其他過程,視圖和查詢使用。因爲更改任何索引都會對現在正在運行良好的其他查詢產生巨大影響,但是如果表缺少任何索引,則任何更改都可能會有所幫助。需要考慮的事情,當你試圖優化這樣的事情是:
- 如何經常是這樣的查詢運行
- 當它運行的它的系統
- 什麼是這個最頻繁的操作 上影響其他進程表,插入或更新?
如果這個查詢每天運行一次,或者很少發生,並且不影響其他進程,我可能會傾向於離開它。但是,如果這是一個運行頻繁和/或影響其他進程的進程,那麼您需要修復它。現在通過修復它,它可以很簡單,只要添加WITH(NOLOCK)
表提示,如果您發現它阻塞,但如果它運行頻繁,然後查看索引和統計信息。
如果你在這個表上有很多插入,那麼任何額外的索引都會影響插入性能,但它會加速更新。然後是索引填充因子等等。我的觀點是,在Sql框中進行性能調整非常複雜,並且大部分時間都需要整個圖片。
所以我建議你在這裏提一些提示,因爲沒有人知道你的系統和你一樣,你可以做出一些決定,並做實驗,並從中學習!啓用您的查詢執行計劃並查看它,看看是否有任何表掃描,它們不好,並且表明缺少適當的索引,關鍵查找也是如此。
但看着你在這裏給出的查詢,並忽略了其他因素,這裏是我的建議。
確保索引中包含employee_number
和course_code
的非聚簇索引。如果是Sql 2008,你可以添加一些包含的列,如果你有其他查詢過濾這兩列,但輸出其他列。至於它們應該在指數中上升還是下降取決於你,但將它們都作爲升序留下。
然後在查詢,使用什麼@Jonathan提出,對於小的修改(+1你!),在表中添加WITH(NOLOCK)提示。這會告訴Sql優化器在讀取表時不要鎖定表,但是您將能夠讀取髒數據。通常不是問題,除非它是一個高度事務性的表,大量的更新和插入一直在進行。
IF EXISTS(SELECT 1 FROM course_tracking WITH(NOLOCK)
WHERE employee_number = @employee_number
AND course_code = @course_code)
BEGIN
UPDATE COURSE TRACKING
END
ELSE
BEGIN
INSERT INTO COURSE TRACKING
END
此外,檢查,如果你統計的數據庫自動更新如果沒有,創建維護作業,將一天一次更新,當服務器是最不活躍。以此爲查詢EXEC sp_MSForEachTable 'UPDATE STATISTICS ? WITH FULLSCAN'
來源
2011-02-15 21:57:12
Ryk
確保`course_code`和`employee_number`都編入索引。覆蓋指數應該可以正常工作。 – JNK 2011-02-15 20:28:07
什麼是SQL Server版本?因爲SQLServer 2008爲你提供了`MERGE`能力,這對於這樣的upserts來說非常棒。 – Matthew 2011-02-15 20:30:16
@JNK,他不需要包括計數的id列嗎? – DForck42 2011-02-15 20:37:31