眾所周知SQL SERVER是微軟的數據庫拳頭產品,有著圖形化友好界面、操作門檻低、部署難度小,一鍵式安裝的特點,受到全球開發者及企業的青睞。從歷代版本說起,經典2000版本是劃時代的里程碑作品,至今還能在各種財務軟件、ERP偶遇一回。
但隨著軟件的升級換代,早期的2000版本從性能、功能上已經難以滿足現行需求的發展,隨之出現了2005、2008、2008R2、2012、2014、2016、2017、2019版本,2005和2008作為2000的實力升級版本,已經在數據庫界扛了多年把子。當然,也經常與另外兩大佬Oracle和MySQL輪流坐老大。
真實案例分析
在很多生產環境中,隨著日積月累,數據量越來越龐大,如今信息爆炸的大數據時代來臨,給它也增加了不小的壓力。
這些年來,對SQL SERVER卡頓、查詢慢、死鎖的問題也經常耳聞。
但說起方法,五花八門,無外乎復雜SQL語句優化,面對龐大的ERP、OA系統,改造難度極大。
所以,在這幾年工作經驗中,總結出一些簡單卻有奇效的方法與大家分享。
2020年年末,朋友緊急邀請,處理了一個棘手案例:
一家本地物流企業,ERP上線三年,系統出現頻繁卡死、一個簡單查詢十幾分鐘,內存占用卻僅8G,企業一度停工,IT部門技術員百思不得其解,老板幾近抓狂。
經過分析,基本情況如下:
Win2012系統,2008R2 32位數據庫,普通機械硬盤,內存16G,僅占用8G,CPU占用穩定4%左右,windows自身反應很慢,桌面窗口屢次殘影。
根據經驗,第一時間查看任務管理器的“性能監視器”,發現硬盤I/O一直居高不下,滿載100%
再看看高I/O進程,居然是SQL SERVER的tempdb文件。
然后大致瀏覽了幾個大表對應的索引,大部分為空或者碎片率100%
看到這,隨行的一位ERP實施工程師皺了皺眉頭,感慨ERP系統語句可能需要進行大幅優化調整。老板一聽,臉頓時沉了下來,這意味著有很多不可預估的風險發生,并且花費大量時間。
老板要求在不停工、停業、傷筋動骨改代碼的情況下,先讓系統運轉起來即可。
大家聽完直搖頭,因為距離天亮開工還不到11個小時了。
簡單粗暴,10個方法調一劑良方
時間一分一秒過去,現場氛圍略微沉寂,讓我有機會冷靜片刻。
既然修改代碼不現實,那就從外圍解決問題。
方法1:SQL SERVER 32位版本開啟AWE,并拆機擴容內存到64G
32位程序無法使用超過4G的內存,數據庫無法有效地利用內存,導致頻繁的硬盤讀寫。開啟后將允許32位數據庫鎖定內存頁,允許使用超過4G的內存,利用內存充分釋放性能。另外,注意在組策略中將sqlserver.exe進程的用戶授予允許鎖定內存頁權限。
方法2:將系統臨時數據庫tempdb.mdf移動到獨立的物理存儲容器
很多SQL語句,諸如 select * into #tmp from table,這里的臨時表#tmp就儲存于tempdb。如果tempdb與主數據庫存在于同一個物理硬盤,當臨時表使用頻繁時,可能造成互相爭奪資源的現象發生,導致硬盤I/O瓶頸。tempdb內的表在SQL SERVER進程每次啟動時會清空??梢岳斫鉃樗皇莔ssql的一個臨時草稿紙。
當然,你也可以用Primo Ramdisk等軟件將內存一部分虛擬成磁盤分區,然后轉移tempdb庫。性能將比SSD更強悍。
方法3:全表索引碎片整理
右鍵管理>維護計劃>新建維護計劃,創建一個全庫全表重新生成索引任務,暫時設置為手動。計劃創建完成后右鍵執行,漫長的等待執行完畢。
方法4:關閉計算機虛擬內存
系統虛擬內存會在硬盤上虛擬一塊區域作為虛擬內存,而硬盤的讀寫速度遠遠慢于內存速度。關閉虛擬內存將強制所有程序使用高速內存運行,降低硬盤I/O。但是關閉虛擬內存可能導致一些問題,非緊急需要或對服務器上各類軟件非常了解,慎重操作。
這里ERP采用服務端占用大量虛擬內存,關閉虛擬內存強制使用更快的物理內存。當然,前提是物理內存足夠大。
方法5:電源管理設置為高性能模式+性能優先級
控制面板,電源管理,將方案設置為高性能模式,再將計算機性能優先級設置為后臺服務。這兩點看似不起眼,但作用明顯。如果電源方案為節能或默認的平衡,CPU將工作在降頻模式,硬件散熱系統也工作在低頻環境,如果溫度過高,還會進一步降低CPU頻率,導致性能下降,win2008以上版本請選擇“卓越性能”,開啟方法請自行搜索。
方法6:SQL Server Profiler跟蹤器找出問題語句
用mssql自帶的工具SQL Server Profiler,設置時間大于2.5秒的執行全部列出,再將截獲的語句復制到SQL Server Managemen,右鍵“在數據庫引擎優化顧問中分析查詢”,它將全自動地幫你分析出索引方案來優化耗時長的語句,只要在分析結果點擊應用,即可獲得大幅性能提升。而這些操作,無需懂任何SQL編程就能簡單完成。性能提升簡直是質的飛躍。
揪出那些拖垮你性能的語句,一鍵優化它。優化效果非常驚艷??赡茉拘枰畮追昼姷牟樵儸F在只需三秒。如上圖,預計估計提高程度:80%,80%這是個什么概念。
方法7:當然別忘了磁盤碎片整理(機械硬盤)
機械硬盤需要定期整理磁盤碎片,否則會降低硬盤讀寫性能,有條件的上SSD,建議組Raid或上云服務器采用云SSD盤。這個就不需要配圖了吧。
方法8:修改數據庫事務隔離級別
MSSQL數據庫隔離級別最低級別為read committed snapshot,它可以將數據庫死鎖概率降到最低,看自身情況開啟。DBCC USEROPTIONS語句可以查看當前的隔離級別
方法9:數據庫設置及服務設置
在管理器中右鍵服務器,屬性>處理器,勾選“提升SQL SERVER優先級”。
再選中數據庫,右鍵屬性>選項,恢復模式:簡單,兼容模式選擇合適的兼容級別
方法10:升級高版本的SQL SERVER ,更換x64位系統
如果現行使用的是SQL SERVER2008及以下版本,建議升級到2014或更高版本,我曾在同一臺服務器上測試裝過2008和2014、2019三個版本,進行10萬條數據的寫入、更新、刪除,得出的結果如下:
可以明顯發現,2014相對于2008有很大提升,2019相對于2014提升并不是非常明顯。2014版本加入了內存表的概念,預計使用得當對性能提升有一定幫助。
畢竟三者相差了多個大版本,微軟總不能只更新了版本號吧~
一頓操作猛如虎
跟蹤器及數據庫引擎優化顧問優化了將近三百多條語句,總共花費了四個多鐘頭時間,全部完成后,老板從宿舍召集一些老員工通宵測試優化結果。
一番操作測試下來,絲滑般順暢,所有卡頓完全消除,查詢基本都是秒出結果,死鎖消失,硬盤I/O穩定維持在2MB/S以下。一籌莫展的臉上露出了久違的舒坦,可以安心地睡個覺。
之后,IT部門除了每周定時執行索引維護外,沒有其他操作,至今未見卡頓。
總結10個簡單有效的方法分享給大家,希望能給正在為此類問題水深火熱的人帶來曙光。
歡迎收藏以備不時之需,歡迎轉發,評論,指正!