2016-05-17 42 views
2

我管理SQL Server 2008 R2單實例服務器。我有一張桌子是我最大的桌子,也是我用得最多的桌子。它基本上是一個事件表,每天記錄大約40萬個事件,並保存13個月的歷史。SQL Server最佳實踐 - 如何管理大型多用表上的索引

爲了這個解決方案,改變這張表或其中的數據的設計不是一個選項。因爲該表是

  • 巨大的(135萬條記錄,41 GB的大小)
  • 使用場組合的衆多
  • 使用一致的結構查詢,查詢都通過工具查詢,以及即席查詢
  • 重要的是查詢要相對快

管理這張表上的索引一直是熊。

該表當前有1個聚簇索引(int標識字段上的PK)和23個非聚簇索引。 Total Index存儲量爲372 GB,比表格本身大9倍。該表每天更新一次,然後所有其他活動都是「SELECT」語句。大多數在WHERE子句中使用的字段都是varchar(50)字段,並且還有一些datetime字段。

在性能方面,該表的查詢很快在幾乎所有情況,所以沒有抱怨那裏......

ASK:
我只是不知道是否有索引此表以一種更好的方式讓它更「通用」,以支持多種查詢方式,而不佔用太多磁盤空間......想法?在這樣的情況下尋找一些高層次的理論或一般最佳實踐。

+0

這取決於您在此表上運行的查詢組合,因爲您表示,此表每天只更新一次,您可以創建不同的索引組合,查看您是否獲得了所需的輸出。沒有看到需要,除非你看到一些問題,你需要試圖快速查詢 – TheGameiswar

+0

有多少列?到目前爲止,您的索引策略有哪些? – SQLChao

+0

@ TheGameiswar - 我的關注更多的是索引存儲的增長......這個表經常被查詢,而當查詢花費的時間比預期更長時,我聽到了這個消息。 :-)修補它並不是最理想的。我只是在我的存儲空間接近最大的時候(不能證明SAN給老闆的成本,並且已經在服務器上獲得了最大的內部存儲空間)。所以我必須開始注意我添加的索引。試圖看看我是否需要專門改變我的方法。 –

回答

1

最佳索引IMO是基於使用情況的 - 運行Profiler,並捕獲針對此表運行的查詢並對這些查詢進行微調。

如果你能夠改變分區或聚集索引策略,這會給你一個很大的提升。

問:爲什麼在用於報告目的的表上的Identity列上存在PK?是否在JOINs中大量使用?如果不是,那僅僅是爲了唯一性嗎?

+1

您也可以使用計劃緩存,它通常用於查找具有較大I/O的查詢的相當可靠的源,並且不需要任何設置/運行。 –

+0

同意基於使用情況的索引...這是如何創建索引到目前爲止。我擔心的是,每次我們添加一個新報表需要以與先前報表不同的方式加入到此表中時,分析和添加新索引可以頻繁地向服務器添加另外16到20 GB的索引數據。嘗試查看是否有更好的方法來執行此操作,而不是爲我們部署的每個報告視圖創建新的自定義索引。 –

+0

關於分區...不幸的是,這不是一個選項,因爲這是一個標準版許可證,而不是企業許可證(不能讓老闆批准企業版許可證的成本)。 –

1

你可以檢查是否有索引可以組合成一個索引。 - INCLUDED列的列順序不相關。例如:

Index 1: 
Key Columns (A, B, C, D, E) Includes (L, M, N) 
Index 2: 
Key Columns (A, B, C, D, E, F, G) Includes (N, M, L) 

所以你可以放棄索引1.但是你可以做更多的I/O,因爲索引2更大。 另一方面,您不必在RAM和磁盤/備份中擁有兩個索引。

它也可以是改變較少選擇性索引列的順序不花費太多。正如您可能知道索引中鍵列的順序應該是從最有選擇性的第一個到越來越少的選擇性列。

您是否要爲實際數據使用與舊數據相同的索引策略?因此,您可以使用過濾後的索引,對較舊的數據使用較少的索引,對較新的數據使用更靈活的索引策略。以前的數據可能無法像今天那樣快速查詢。但是與新數據相比,查詢的頻率如何?

+0

我同意你的方法。過濾掉的索引是我沒有想到的,所以我也會考慮一下,看看是否有一些查詢可以限制範圍以減少磁盤使用。我假設在重建索引或將新數據插入表時,將應用創建索引語句的「WHERE」子句?例如,如果我在過濾器上使用WHERE dtmHandledDate> = DATEADD(DAY,-60,GETDATE()),那麼當索引不再匹配WHERE時,記錄將從索引中刪除?我只假設在重建。我會研究一下。感謝您的輸入! –

+1

如果您插入,更新,刪除行(以及TRUNCATE TABLE :-),並且行中的數據符合索引的過濾器謂詞,則只會更新已過濾的索引。你不能使用像DATEADD這樣的非確定性函數。這意味着SQL-Server將不得不經常檢查每個謂詞。但事實並非如此。所以你必須在過濾器的WHERE-Clause中使用一個固定的日期範圍。要更改過濾器謂詞,請使用ALTER INDEX .... – CPMunich

+0

有趣。謝謝你的提示!我一定會更多地關注它。 –