722
京東網上商城
Delphi 程序錯誤寫法造成Oracle數據庫負載異常
本文講的是Delphi 程序錯誤寫法造成Oracle數據庫負載異常
作者介紹
張洪濤 富士康 DBA
注意:本文涉及的問題在9i的環境中測試的,經驗證,同樣適用於11g.
在用Toad的SGA Trace工具監控我們的Oracle 9.2.0.8 Patch 31古董數據庫時發現一條奇怪的SQL,它占到數據庫整體邏輯讀50%以上,SQL如下:
這條SQL單次執行邏輯讀不到900,但執行非常頻繁,它本意想查詢HRM.ORGANIZATION表的表與索引信息。
程序員應該不會特意寫這種SQL,那它到底來自哪裏?
通過MODEL_NAME,找到SQL對應的Session,並做10046 Trace分析這條SQL與
SELECT departmentname FROM hrm.organization WHERE departmentid=:1交替執行。DB層麵已經很難再有什麼有價值線索,隻有請開發提供源碼分析。
這個程序使用Delphi7開發,很快開發將源碼發來,代碼如下:
分析Delphi程序在執行以下語句時調用了異常SQL。
ADOQuery2.SQL.Add(str_4);
ADOQuery2.Open;
ADOQuery2.First;
程序員正確使用了Delphi ADOQuery控件添加了SQL文本,並調用Open方法執行SQL,但為何要再調用First方法?
ADOQuery的First方法本意為定位到結果集的第一條記錄。因為departmentid為主鍵,SELECT必返回一條記錄,此步應為多餘。請開發人員屏蔽掉ADOQuery2.First;再上線新版程序觀察。
第二天這條詭異SQL仍被監控到,看樣子屏蔽掉First方法調用並沒有找到Root Cause,需要繼續研究源碼。
仔細分析此段程式,ADOQuery2調用Select語句時並沒有使用綁定變量,是否是因為SQL硬解析造成異常SQL調用?
依此思路再將程序改寫成以下使用綁定變量形式,並請程序員再次編譯程序並上線。
第三天這條詭異SQL又被監控到,到底是哪裏還有問題,還是解決問題的思路錯了?再回到前一天改過的源碼......
文本改為綁定變量沒有錯,是否Delphi ADOQuery控件執行Add方法時這條奇怪的SQL被調用?依據這個思路,再修改第三版程序,將ADOQuery 的Add方法調用放到While循環外,並請程序員重新編譯上線。
現在在While循環外定義SQL,在While循環內給變量賦值並執行SQL。
繼續監控發現這條詭異SQL終於消失了。確認Delphi ADOQuery調用Add方法時調用這條問題SQL獲得對應表與索引信息。將Add方法移到While 循環外就徹底消除了循環內對問題SQL的調用。這也是Delphi ADOQuery控件在循環內執行SQL的正確方法。
Remark:
因為我們還有Informix 7 史前數據庫,公司Policy規定不可用ODBC訪問接口直接訪問它,且Oracle 11.2 Gateway又不支持對Informix 7的訪問,所以隻有保留Oracle 9.2.0.8以利用其異構服務訪問Informix 7。
原文發布時間為:2017-09-21
作者: 張洪濤
本文來自雲棲社區合作夥伴“ 數據和雲”,了解相關信息可以關注“ 數據和雲”微信公眾號
最後更新:2017-09-22 16:34:16