哇哦,光陰似箭!歡迎回到性能調優培訓的最后一期。今天我會詳細講下SQL Server里的數據庫維護,尤其是索引維護操作,還有如何進行數據庫維護。
索引維護
作為一個DBA,數據庫維護是你工作中非常重要的一部分,讓數據庫獲得最佳性能。一個SQL Server數據庫就像一輛車:它需要經常的檢查來保證運行沒有問題,副作用,且擁有最大可能的性能。SQL Server數據庫最重要的部分是它的索引及其對應的統計信息對象。SQL Server運行一段時間后會有索引碎片,統計信息必須更新,這樣的話查詢優化器才可以為你生成“足夠好”的執行計划。
我們來詳細看下這2個東西。索引(聚集,非聚集)會產生碎片。索引意味着邏輯和物理排列順序不再一致。如果你在傳統旋轉存儲上存儲你的數據庫,索引碎片在你的存儲子系統里帶來隨機I/O,與快速的循序I/O相比,它非常耗時。下圖展示了索引碎片。
微軟建議下列索引維護的最佳實踐:
- 碎片低於10%:不進行維護
- 碎片在10-30%:進行索引重組操作
- 碎片大於30%:進行索引重建操作
除此之外,索引重組和索引重建操作應該只有在葉子層的頁數至少有10000頁才可以。如果你沒有達到這個閾值,你不會看到隨機I/O帶來的副作用消失。索引重建(Index Rebuild)操作會完全重建你的索引。它是一個在事務日志里完全記錄的“大”事務。在99%進度的時候回滾你的重建操作是個非常不好的想法,因為SQL Server需要把已做過的(有益的一面)全部重做一遍。因為你的回滾會花費很長時間。因為索引重建會重新生成你的整個索引,你的統計信息也會用全掃描更新。
另外,因為它是個大事務,如果這時你使用基於事務日志的HA技術就會有問題——例如數據庫鏡像或AlwaysOn可用組。SQL Server需要發送你的整個事務到鏡像(或復制的地方)。那就意味着你的網絡流量里有大量的事務日志記錄。這對你的HA策略會有很大的副作用。
作為一個替代方法,索引重組(Index Reorganize)操作只處理你的索引的葉子層,重組葉子層的邏輯排序。因此,索引重組不會為你更新統計信息。索引重組只包含多個小的系統事務。因此它不會在事務日志上帶來太大壓力,因為虛擬日志文件可以為了更快的重用而被標記。索引重組操作對使用數據庫鏡像或AlwaysOn可用組都是有益的,因為使用索引重組操作你沒有給網絡流量里倒入大量的事務。
如何進行維護操作
我經常被問到的問題是在SQL Server里如何進行維護操作。我絕不,從未建議SQL Server提供的數據庫維護計划(Database Maintenance Plans)。使用這些維護計划你使用大錘往SQL Server里砸:維護計划會重組/重建你的索引而不管它們的實際碎片!
我已經看過運行整晚在索引上進行索引重建的維護計划,盡管有些索引沒有碎片。使用剛才提到的數據庫維護計划,你就不能依據索引碎片情況進行維護。重組和重建索引是要根據索引碎片等級來的。因此我從不推薦這些數據庫維護計划給任何人!
我推薦使用Ola Hallengren提供的SQL Server維護解決方案。這個解決方案包含一些列的存儲過程,使用它們你可以繼續寧數據庫一致性檢查,備份,還有索引維護操作。索引碎片等級就是你提供存儲過程的參數值。我們來看看下列IndexOptimize存儲過程的調用:
1 EXEC [master].[dbo].[IndexOptimize] 2 @Databases = 'AdventureWorks2012', 3 @FragmentationLow = 'INDEX_REBUILD_OFFLINE', 4 @FragmentationMedium = NULL, 5 @FragmentationHigh = NULL, 6 @FragmentationLevel1 = 10, 7 @FragmentationLevel2 = 30, 8 @PageCountLevel = 10000, 9 @SortInTempdb = 'N', 10 @MaxDOP = NULL, 11 @FillFactor = NULL, 12 @PadIndex = NULL, 13 @LOBCompaction = 'Y', 14 @UpdateStatistics = NULL, 15 @OnlyModifiedStatistics = 'N', 16 @StatisticsSample = NULL, 17 @StatisticsResample = 'N', 18 @PartitionLevel = 'N', 19 @TimeLimit = NULL, 20 @Indexes = NULL 21 @Delay = NULL, 22 @LogToTable = 'Y', 23 @Execute = 'Y' 24 GO
從代碼里你可以看到,你可以指定不同的碎片等級作為參數(FragmentationLevel1, FragmentationLevel2)。最后對於這些碎片等級你指定你想要進行的索引操作(FragmentationLow, FragmentationMedium, FragmentationHigh)。在SQL Server里它是非常簡單,卻是非常強大的進行索引維護操作的方法。試下——用了包你忘不了!!
小結
在今天的性能調優培訓里,我們談了SQL Server里的數據庫維護。你已經學到經常進行索引維護操作來擺脫索引碎片非常重要。因為索引碎片會在存儲子系統引入隨機I/O,它會降低磁盤讀取操作。另外我想你展示通過使用Ola Hallengren提供的SQL Server維護解決方案進行非常高效的索引維護操作。
我希望和我一起的24個星期的性能調優培訓很有收獲,你已經學到了SQL Server里一些新的東西,尤其是性能調優和故障排除。歡迎大家給我留言,把你的想法告訴我!!再一次感謝您關注性能調優培訓,感謝您和我一起度過這個24個星期的培訓!! 謝謝您的一路陪伴!!!
