上周五碰到開發的請求協助解決數據預定程序中對單頭等幾個表檢索數據時檢索條件尾數是9的數據特別慢。第一時間想到的是否如下幾個問題:
1、數據庫相應數據最多;
2、數據表進行了分區,而相應數據落在的分區性能存在問題;
3、檢索該批記錄的會話很多;
但很快排除了以上幾種可能,因為後續的調查由如下發現:
1、查詢了相應數據,尾數0-9的數據幾乎平均分布;
2、直接用SQLSERVER查詢分析器查詢速度很快;
到此大家基本都認為數據庫不存在問題,但是如下的調查感覺又讓人陷入了迷茫。在相同網段的其他服務器上建立了相應的用戶、表、數據進行測試,發現程序取數據速度很快,和生產數據庫的區別就是數據量,還有表結構(為了測試偷懶全部字段定義為VARCHAR,後來執行程序異常才迫不得已把部分字段改成了date)。雖然測試過程不嚴謹,但這又似乎能把問題的天平向數據庫這邊傾斜。
就這樣周末測試摸索的一天很快過去了,家裡的無線網絡6塊錢一小時開銷也實在不小,周一一大早就來到公司,回歸有限寬帶的懷抱,但郁悶的生產庫我們只有查詢幾個字段的權限,我動不了。於是聯絡上游數據單位,盤算著通過看執行日志等手段把問題范圍進一步縮小,而要對方配合卻要工作聯系單。想想還是先花半天時間有把我們這邊的問題可能性全部掃除了才開這個聯系單。
如何進一步縮小差距, 接下來來看看網絡是否有問題,巧的是數據庫服務器IP末尾是9,而恰恰是末尾為9的數據,為了排除該問題,進行了一系列的探索:
1、更換測試數據庫服務器,發現取數據速度正常;
2、在測試程序客戶段增加HOST映射,但取數據速度依舊;
3、在同一網段服務器部署測試程序。
以上三種測試均表明網絡異常的可能性越來越小,至少在我們IDC和分中心內網之間的網絡互聯是正常的。
再鎮定想想數據庫查詢為什麼慢,只有三個層面的原因,數據庫本身的性能問題、網絡問題、客戶端問題,而當今問題最多的無疑就是客戶端程序異常,既然生產數據庫無法做有效的調試,那麼我們得把我們的問題盡量掃除。
於是請開發部的侯文傑把相關代碼的時間戳進一步細化,文傑幾分鐘內就提供了代碼,立即上傳測試發現在ps = conn.prepareStatement和ps.setString效率上均沒有問題,而rs = ps.executeQuery();就是罪會禍首。
再來仔細審視數據,一個念頭突然閃現,既然SQLSERVER客戶端查詢正常,會不會是程序組裝的SQL存在問題。於是立即要求文傑給我一個測試任意SQL語句的接口,通過這個接口,我可以隨心所欲的測試cout(*),like等語句的性能(悲劇的是很長時間沒有碰代碼,我的開發環境已經無法運行)。一個小時後我得到了這個接口,接下來發現了令人興奮的結果:
我自己組裝的一條完整的SQL語句通過程序裝載後執行迅速,而另外一條通過JDBC SETSTRING組裝的同樣的SQL語句,竟然還是出奇的慢。