4

我們遇到SQL超時並已發現瓶頸是審計表 - 我們系統中的所有表都包含導致新審計的插入,更新和刪除觸發器記錄。刪除主鍵(聚集索引)以提高插入性能

這意味着審計表是系統中最大和最繁忙的表。然而,數據只是進來,並且從來沒有出現(在這個系統下),所以不需要select性能。

運行select top 10返回最近插入的記錄而不是'第一個'記錄。當然,order by的作品,但我希望一個選擇頂部應該根據他們在光盤上的順序返回行 - 我期望會返回最低的PK值。

有人建議我們放棄聚集索引,實際上也是主鍵(唯一約束)。正如我前面提到的,在這個系統中不需要select

聚簇索引在表上創建什麼類型的性能影響?有沒有索引,非集羣,無密鑰表的(非選擇)分支是什麼?還有其他建議嗎?

編輯

我們的審計涉及CLR函數,現在我有沒有& PK,索引,FKS等基準來確定的CLR函數&的約束控制下的相對成本。

調查結束後,糟糕的表現與insert聲明無關,而是CLR功能,它編排了審計。在刪除CLR並改爲使用直接TSQL處理程序後,性能提高了20倍。

在測試過程中,我還確定聚集索引和標識列對插入時間沒有什麼影響,至少相對於發生的任何其他處理而言。

// updating 10k rows in a table with trigger 

// using CLR function 
PK (identity, clustered)- ~78000ms 
No PK, no index - ~81000ms 

// using straight TSQL 
PK (identity, clustered) - 2174ms 
No PK, no index - 2102ms 

回答

6

根據金佰利特里普 - 索引的女王 - 在桌子上有一個聚集索引實際上有助於INSERT性能:

聚集索引的爭論持續

  • 鑲片在快與堆相比,聚簇表(但僅在「右」 聚簇表中)。此處的主要問題是 ,IAM/PFS中用於確定堆 中的插入位置的查找比羣集表(其中插入位置已知, 由羣集鍵定義)中的查找速度慢。插入到定義訂單(CL)的 表中並且該訂單 不斷增加的插入更快。

來源:博客文章叫The Clustered Index Debate Continues....

+1

我發現這一點在桌子尺寸增加時尤其如此。 –

2

一個表沒有的關鍵?甚至沒有一個自動遞增的代理鍵? :(

只要關鍵是單調遞增對插入索引維護應該是不錯的 - 它只是「在最後補充說:」「集羣」只是意味着該表的物理佈局遵循指數。 (因爲數據是索引的一部分)只要索引沒有分段(參見單調增加位),那麼集羣本身/數據將不會在邏輯上分散,這不應該是性能問題。 (如果有更新,則羣集是一個稍微不同的故事:更新的記錄可能「增長」並導致碎片)。

我的建議是,如果那是選擇的路線,那麼... 長凳用實際數據/負載標記,然後決定是否保證這些建議。很高興看到這種變化是否已經決定,爲什麼。

快樂編碼。


此外,當爲了任何依賴除此之外,從ORDER BY通過設計存在缺陷。它現在可能會工作,但它是一個實現細節,可能會以微妙的方式進行更改(就像不同的查詢計劃一樣簡單)。使用自動遞增鍵時,ORDER BY DESC總是會產生正確的結果(請記住,自動遞增ID可以跳過,但除非「重置」,否則它們將總是基於插入順序增加)。

+0

乾杯。我不依賴訂單,我只是在管理器中使用它來證明索引不能確保行以一致的方式放置在磁盤上。 –

3

這個scenarion的一個偉大的測試腳本和描述可在蒂博爾Karaszi的博客:SQLblog.com

我的數字並不完全符合他 - 我見更多在批處理語句上的差異比我對每行語句的差異。

由於行數在100萬左右,所以我相當一致地在聚集索引上獲得單行插入循環,其執行速度比非索引(聚集大約97%,只要非索引)要快。

相反,批處理插入(10000行)更快地進入非索引而非聚集索引(任何集羣插入時間的75%-85%)。

clustered - loop  - 1689 
heap  - loop  - 1713 
clustered - one statement - 85 
heap  - one statement - 62 

他介紹什麼在每次插入:

堆:的SQL Server需要找到該行應該去。爲此,它 使用一個或多個IAM頁面作爲堆,並且它將這些 交叉引用到數據庫文件的一個或多個PFS頁面。國際海事組織,應該有 在這裏有一個明顯的開銷的潛力。甚至更多的是,有許多 用戶敲擊同一張桌子,我可以想象阻止(等待) PFS以及可能還有IAM頁面。

Clustered table:現在,這已經很簡單了。SQL服務器導航 聚集索引樹並查找行應該去的地方。由於這是一個不斷增加的索引鍵,所以每行都會到表 (鏈表)的末尾。