楊久莉,石國玲,段季芳
(合肥京東方光電科技有限公司 自動化技術部,合肥 233100)
基于MES系統(tǒng)業(yè)務邏輯的性能優(yōu)化
楊久莉,石國玲,段季芳
(合肥京東方光電科技有限公司 自動化技術部,合肥 233100)
MES是面向制造企業(yè)車間執(zhí)行層的生產信息化管理系統(tǒng),在系統(tǒng)初期由于數據量小、系統(tǒng)壓力輕,其系統(tǒng)的缺點不易暴露出來。隨著時間的推移,各種問題都會出現。在性能調優(yōu)的方法中最常用的方法是SQL調優(yōu),但是有的SQL已經是最優(yōu),只能通過修改業(yè)務邏輯來實現調優(yōu)的目的。本文列舉幾個比較經典的案例,以期為MES系統(tǒng)開發(fā)和維護人員提供幫助。
MES系統(tǒng);業(yè)務邏輯;性能;優(yōu)化
MES系統(tǒng)的性能直接關系到工廠一線的生產,性能低下的系統(tǒng)功能會直接影響到工廠的生產進度,從而間接影響到產能。因此,高效的業(yè)務執(zhí)行在MES系統(tǒng)中至關重要,在生產總數據量龐大、單位時間內業(yè)務處理量高的繁忙系統(tǒng)中更加明顯。本文將結合生產制造行業(yè)的MES系統(tǒng)特征,以實際業(yè)務系統(tǒng)中出現的業(yè)務查詢和更新時性能問題作為出發(fā)點,結合業(yè)務邏輯,有效地實現了業(yè)務處理性能的改善。
應用的SQL性能一般通過AWR報告來分析,出現報告中Top SQL上的語句一般需要進行性能分析。通過觀察AWR發(fā)現有兩條查詢占用33.7%的DB Time,其SQL是用來查詢系統(tǒng)表的數據,且使用者是用戶。
經分析,這兩條SQL是應用使用SimpleJdbcCall調用存儲過程或者函數產生的。SimpleJdbcCall是一個多線程、可重用,用來調用存儲過程或者函數的工具,它通過提供元數據的處理方式來簡化對基本存儲過程和函數的訪問。在執(zhí)行存儲過程或者函數時,只需要提供執(zhí)行存儲過程或函數的名字和用Map表示的相應的參數,這些參數的名字將會與創(chuàng)建存儲過程或者函數時定義的參數名進行匹配。
這種方式為應用程序開發(fā)者簡化了代碼,但是對于存儲過程或者函數使用較多的系統(tǒng),則會出現資源爭用的情況。SimpleJdbcCall提供的addDeclaredParameter方法來指定每個變量的類型,就可以避免SimpleJdbcCall在執(zhí)行存儲過程或者函數時先調用元數據的過程。因此,將應用上所有的函數中增加了addDeclaredParameter這個方法,完成優(yōu)化后不但提高業(yè)務的處理速度,也降低對DB資源的爭用情況,兩個查詢從Top SQL中消失。
筆者觀察AWR發(fā)現有一條SQL,它的平均執(zhí)行時間為0.2s,占了接近1.73%的DB Time,但是對應表是一個20M的小表,這樣的查詢出現在Top SQL中絕對是有問題的。分析其執(zhí)行計劃,CBO選擇IDX_01,Cost數值為653。
對數據及查詢結果進行分析,此表總數據約為24萬條,此查詢的結果返回13條基準信息。IDX_01索引列名為(FACTORYNAME),而整張表中此列值相同,沒有任何選擇度;其次,此表還有一個基于(SUPERAREANAME)列的索引IDX_02,而要查詢出來的數據所對應的SUPERAREANAME為NULL值。即使在Where條件上SUPERAREANAME的篩選條件,基于以上數據分布和Oracle的特性,該CBO不會選擇IDX_02。綜合業(yè)務分析,最終將這13條數據的SUPERAREANAME列填寫具有區(qū)分度的數據,并將此列加到Where條件中。再次分析執(zhí)行計劃,Cost數值由652降低為2。再次查看AWR,此條SQL從Top SQL中消失了。
以上案例可以看到,對單表進行查詢優(yōu)化時,先對數據和現有的Index進行分析,有時候不需要建立額外的Index,而是對數據稍作變動,就能解決問題。由于B*Tree索引不存儲Null值,所以查詢NULL值數據時,Oracle會因為Null值的存在而放棄索引。為了此種情況發(fā)生,使用默認值代替NULL值,或者在建立index時使用聯(lián)合索引而非獨立索引。
用戶一直反映某個查詢較慢,經常因為查詢時間較長而收到超時錯誤。分析此查詢的SQL語句,語句并不復雜,當前使用的索引也是最優(yōu)的。通過tkprof工具對Trace文件進行分析,發(fā)現SQL執(zhí)行的主要時間是花費在數據獲取(fetch)上,total數據為:disk (51163)、query(76985)、current(0)、rows(1764),平均每行所需的block數=(query+current)/rows,此查詢平均讀取每行需要的Block數約為44塊。正常情況,訪問一條數據的速度由索引的高度和回表查詢的IO決定,一般索引高度都在3層以下,正常查詢一條數據,IO在4個以內。即訪問一條數據需要訪問的數據塊的個數不超過4個,本案例中達到44塊,說明索引的掃描效率太低,或者說該索引不合適該查詢。經過數據分析發(fā)現,需要查詢的數據只占整個表的小部分,總共73 639行數據,且分布在67 041個數據塊中,因此考慮根據數據狀態(tài),將大表拆分,如果再建立合適的索引,查詢效率就會非常的高。
此表由一個工廠和庫房共用,數據量為61Gb、數據為79 934 965行,數量巨大。如果直接在原表中建立一個十列信息的聯(lián)合索引,則會占用12G左右的空間。如果將工廠和庫房的數據分開,則需要停線。經過綜合分析考慮,將此表中車間數據放到一張單獨的表中,并在上面建立全部數據的Index。
更改后,再次分析Trace中的執(zhí)行計劃,得到total數據為:disk (0)、query(1757)、current(0)、rows(1784)從磁盤上的數據文件中物理讀取的塊的數量由51 163個降低為0個,平均讀取每行需要的Block數也降低到1塊,實際執(zhí)行時間也由將查詢速度由原來首次執(zhí)行的2分32秒減少到781毫秒。
發(fā)貨在FGMS中一直是比較慢的操作,由于需要處理的數據比較多,處理速度一直很慢。SQL已經是最優(yōu),應用處理方式由API改為存儲過程,更新方式也改為最快的BULK處理方式,但是在遇到數據量大的發(fā)貨單,仍然需要很長時間。發(fā)貨數量超過30W的發(fā)貨單,由于處理時間超過TimeOut(20分鐘)的時間,應用直接報錯。每到月底發(fā)貨量大的時候,用戶體驗更差。在AWR的TOP SQL中,此業(yè)務在15分鐘內執(zhí)行11次,平均時間約81 s,占整個DB Time的5.43%。
此存儲過程里設計的查詢語句及更新方式都是最佳方式,業(yè)務的邏輯處理方式也經過了很多次的優(yōu)化。除了提高硬件性能外,如果保持現有邏輯已經沒有其他提高處理速度的方法。發(fā)貨時,用戶只關注發(fā)貨單及Pallet的信息變化情況,不會觀察Panel的信息情況,故采用了異步處理的方式,先更新Pallet數據及發(fā)貨單信息并將結果反饋給用戶,在用另一個進程更新Panel信息。
此方法只適用于對部分數據更新實時性要求不高、且異步執(zhí)行部分都保證更新成功的情況,否則會造成數據不一致,影響后續(xù)業(yè)務的處理。
一個系統(tǒng)要穩(wěn)定地、高效地運行,離不開持之以恒的系統(tǒng)調優(yōu)。調優(yōu)的方法中SQL優(yōu)化是最直接、最方便,見效最顯著的,但并非所有的問題都是能通過SQL調優(yōu)來解決的。當SQL已經沒有優(yōu)化空間時,不妨對業(yè)務邏輯或者業(yè)務數據進行變動,來達到系統(tǒng)優(yōu)化的目的。從傳統(tǒng)的“供給”改為“供需”,節(jié)約資源,降低投入。
主要參考文獻
[1]陳冠星.企業(yè)應用開發(fā)中Oracle的SQL優(yōu)化[J].軟件導刊,2014(12).
[2]羅時飛.精通Spring——深入Java EE開發(fā)核心技術[M].北京:電子工業(yè)出版社,2008.
[3]陳雍,謝旭升,魏根芽.Oracle B*樹索引內部機制及其應用的研究[J].計算機與現代化,2008(10).
[4]譚懷遠.讓Oracle跑得更快——Oracle 10g性能分析與優(yōu)化思路[M].北京:電子工業(yè)出版社,2010.
10.3969/j.issn.1673 - 0194.2016.16.039
TP311.52
A
1673-0194(2016)16-0059-02
2016-07-08