Jdbc访问mysql查询聚合函数_JDBC连接参数设置对Oracle数据库的影响分析
一次數據庫性能問題處理引發的JDBC參數設置思考
近期某環境下系統,出現大面積頁面訪問緩慢情況,每個頁面交易響應時間2-5秒,嚴重超過平日訪問閾值。
經排查分析,問題主要出現在數據庫,生成AWR得到32C的數據庫DBtime每小時采樣達到4800。進一步分析發現主要等待事件library cache lock,library cache:mutex X。
進一步分析發現DB主要耗時在SQL解析及解析失敗上。
生成10035事件,發現數據庫日志中有大量解析失敗錯誤,且解析失敗的SQL全部帶有ROWID列。
將該類SQL反饋研發部門,反饋未在SQL中添加ROWID。那么ROWID是從何而來的呢,查詢相關資料最后定位到JDBC連接參數設置不合理。
那么JDBC連接有哪些參數,各個參數作用是什么,參數設置會對SQL解析產生什么樣的影響呢?帶著這些問題,筆者對JDBC參數設置對SQL解析影響做了針對性實驗,大家跟著我來一探究竟吧。
JDBC連接參數說明
JDBC連接數據庫主要有兩個類分別是PreparedStatement和Statement,兩個類可以帶三個參數分別是:ResultSetType、ResultSetConcurrency、ResultSetHoldability。由于參數ResultSetConcurrency和ResultSetHoldability對數據庫連接影響小,且使用限制較多,因此這里重點介紹參數:ResultSetType。
ResultSetType
ResultSetType的可選值有三個,每個值及對應的作用如下:
ResultSet.TYPE_FORWARD_ONLY:為空時默認值,該值支持結果集前滾遍歷操作。
ResultSet.TYPE_SCROLL_INSENSITIVE:該值支持結果集后滾,隨機,取后,取前等操作,當其它會話對數據庫中數據做出更改時,結果集不隨之刷新。
ResultSet.TYPE_SCROLL_SENSITIVE:該值支持結果集后滾,隨機,取后,取前等操作,當其它會話對數據庫中數據做出更改時,改更會刷新到本結果集中,使結果集中數據與數據庫數據實時一致。
連接參數測試
測試環境情況如下表:
在測試數據庫中建表psname,psdept,psobj并插入數據,表結構如下:
在Oracle中每次程序調用前清空數據庫緩存(alter system flush shared_pool清空緩存便于觀察SQL執行情況),程序調用結束后查詢V$SQL視圖,查看解析執行的SQL。
參數設置對解析影響
ROWID是Oracle用于查詢表中一行記錄的地址,一旦查詢中出現了SUM,DISTINCT等聚合或去重函數,獲取的數據與單行記錄地址不再一一對應,因此多表連接、單表查詢帶聚合函數、數據去重等SQL解析過程不會出現ROWID,如果出現ROWID則會報解析錯誤。
測試方法:
設置JDBC參數ResultSetType=ResultSet.TYPE_FORWARD_ONLY。
在數據庫服務端執行:alter system set events '10035 trace name context forever,level 1',跟蹤解析SQL。
執行程序查看Oracle內部視圖V$SQL執行解析結果并截圖。
調整ResultSetType值為TYPE_SCROLL_SENSITIVE和TYPE_SCROLL_INSENSITIVE重復1、2步驟執行測試。
比對不同參數設置下Oracle中V$SQL顯示結果,參數設置對數據庫解析影響。
1)測試一,單表簡單SQL1:select ID,NAME from psname。
測試結果如下表,執行過程后臺未見解析報錯(如圖3-0),在測試過程中當ResultSetType為TYPE_SCROLL_SENSITIVE時數據庫執行會自動加入rowid列。其中12C給rowid自動增加一個別名(如圖4-1),11G則不會(如圖4-2)。
圖3-0 10035事件記錄的日志,無錯誤輸出
圖3-1 V$SQL查詢的最終執行結果
圖4-1 V$SQL查詢的最終執行結果
圖4-2 V$SQL查詢的最終執行結果
2)測試二,單表帶聚合函數或去重SQL語句:
① select ?count(ID) as SUM,dept_id from psname group by dept_id。
② select DISTINCT(OWNER) as OWNER, OBJECT_TYPE FROM TEST001.PSOBJ。
經測試ResultSetType設置為TYPE_FORWARD_ONLY,TYPE_SCROLL_INSENSITIVE編譯不報錯,解析執行正常。連接參數ResultSetType設置為TYPE_SCROLL_SENSITIVE時,解析會報錯,由于數據庫自身編譯糾錯機制,最終數據庫執行結果正常,該情況測試結果如下表:
圖5-1 10035事件記錄的報錯日志
圖5-2 V$SQL查詢的最終執行結果
圖6-1 10035事件記錄的報錯日志
圖6-2 V$SQL查詢的最終執行結果
3)測試三,表關聯查詢SQL3:select
n.id,n.name,d.dept_name from TEST001.PSNAME n ,TEST001.psdept d where n.dept_id=d.dept_id and d.dept_name='Sales'。
經測試ResultSetType設置為TYPE_FORWARD_ONLY,TYPE_SCROLL_INSENSITIVE編譯不報錯,解析執行正常。連接參數ResultSetType設置為TYPE_SCROLL_SENSITIVE時,解析會報錯,由于數據庫自身編譯糾錯機制,最終數據庫執行結果正常,該情況測試結果如下表:
圖7-1 10035事件記錄的報錯日志
圖7-2 V$SQL查詢的最終執行結果
4)測試四,帶條件全列查詢SQL4:select * from psname where dept_id=2。
經測試ResultSetType設置為TYPE_FORWARD_ONLY,TYPE_SCROLL_INSENSITIVE編譯不報錯,解析執行正常。連接參數ResultSetType設置為TYPE_SCROLL_SENSITIVE時,解析會報錯,由于數據庫自身編譯糾錯機制,最終數據庫執行結果正常,該情況測試結果如下表:
圖8-1 10035事件記錄的報錯日志
圖8-2 V$SQL查詢的最終執行結果
5)結論:從以上測試情況看出,當ResultSetType等于TYPE_SCROLL_SENSITIVE時,所有SQL編譯過程均會在查詢結果集前增加ROWID列。當增加ROWID產生語法解析錯誤時(通過10035事件生產的日志可知),數據庫通過內部糾錯算法得到正確SQL再執行,于是在V$SQL表中看到不帶ROWID的正確已執行的SQL。當JDBC參數ResultSetType等于TYPE_FORWARD_ONLY,TYPE_SCROLL_INSENSITIVE時SQL解析都不會增加ROWID,此兩種情況下SQL執行前后完全一致,數據庫日志無解析報錯輸出。
在測試過程中還通過調整不同的環境因素進行測試,發現數據庫版本、驅動版本、JDK版本對數據庫解析后ROWID產生無影響,對比分析如下表:
參數設置對查詢更新數據影響
測試說明:根據參數解釋當resultSetType為TYPE_SCROLL_SENSITIVE時,查詢結果集會隨著數據修改動態更新,其他值無此類特性因此此處測試只測該情況即可。
測試過程:
① 設置JDBC連接參數ResultSetType=ResultSet.TYPE_SCROLL_SENSITIVE。
② 調用程序執行查詢。
③ 進入斷點,更新psname表中dept_id字段值。
④ 查看JAVA程序輸出圖,查看數據庫表中結果值圖,斷點循環取值時查看resultset對應ID值。若JAVA輸出結果集與數據庫查詢一致表明,數據動態更新。
測試結果如下表:
圖9:JAVA程序輸出結果
圖10:數據庫查詢結果
結論:JDBC連接參數ResultSetType設置為TYPE_SCROLL_SENSITIVE均不會動態更新結果集。
參數設置對JVM影響
測試方法:調整JVM堆大小,查詢數據庫大表結果集來測試不同參數對查詢結果集影響。
測試過程:
① 將JVM大小設置成-Xmx128m -Xms64m -Xmn32m -Xss16m。
② 執行SQL向表PSOBJ插入150萬條數據,使表數據大于128M。
③ 設置參數ResultSetType=ResultSet.TYPE_FORWARD_ONLY,程序中執行如下查詢:
④ 執行程序查看控制臺輸出結果并截圖。
⑤ 調整ResultSetType值為TYPE_SCROLL_SENSITIVE和TYPE_SCROLL_INSENSITIVE重復1、2步驟執行測試。
測試結果如下表:
圖13
圖14
結論:當查詢結果集大于JVM時,Oracle在ResultSetType為TYPE_FORWARD_ONLY時正常查詢,其他值時內存異常;MySQL在所有情況下都會出現內存溢出的情況。
JDBC參數設置建議
從以上測試中我們不難發現,由于開發人員對JDBC連接參數設置不合理,導致了數據庫解析SQL產生大量報錯,引起了library cache lock,library cache:mutex X等待事件,造成數據庫性能急劇下降,最終造成業務系統響應嚴重超時。
由此建議JDBC中ResultSetType參數設置:若只做一般查詢默認值即可;
若需要對結果集進行遍歷、比較等相關操作可設置為TYPE_SCROLL_INSENSITIVE;
不推薦使用TYPE_SCROLL_SENSITIVE,因為該參數不會動態更新結果集,且該參數可能導致數據庫SQL解析錯誤而執行二次解析消耗數據庫資源;
若查詢結果集過大,建議使用默認,避免結果集過大造成JVM內存溢出。
總結
以上是生活随笔為你收集整理的Jdbc访问mysql查询聚合函数_JDBC连接参数设置对Oracle数据库的影响分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java 管理对象是什么_Java工程师
- 下一篇: mac python3.8上怎么安装py