讀取單個醫生超過2000份病例報錯

今天在修改search的建立索引的程序的時候,發現了這個錯誤

 

使用jdbc讀取SQLServer2005的一個表全部記錄,該表具有10W記錄,結果發生以下錯誤:

Java代碼 複製代碼

  1. com.microsoft.sqlserver.jdbc.SQLServerException: 系統內存不足。請對大型 ResultSet 使用服務器端遊標: Java heap space。ResultSet 大小:236,535,956。JVM 總內存大小:312,213,504。   

  2.     at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDriverError(Unknown Source)   

  3.     at com.microsoft.sqlserver.jdbc.DBComms.receive(Unknown Source)   

  4.     at com.microsoft.sqlserver.jdbc.SQLServerStatement.doExecuteStatement(Unknown Source)   

  5.     at com.microsoft.sqlserver.jdbc.SQLServerStatement$StatementExecutionRequest.executeStatement(Unknown Source)   

  6.     at com.microsoft.sqlserver.jdbc.CancelableRequest.execute(Unknown Source)   

  7.     at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeRequest(Unknown Source)   

  8.     at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeQuery(Unknown Source)  

Java代碼  收藏代碼

  1. com.microsoft.sqlserver.jdbc.SQLServerException: 系統內存不足。請對大型 ResultSet 使用服務器端遊標: Java heap space。ResultSet 大小:236,535,956。JVM 總內存大小:312,213,504。  

  2.     at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDriverError(Unknown Source)  

  3.     at com.microsoft.sqlserver.jdbc.DBComms.receive(Unknown Source)  

  4.     at com.microsoft.sqlserver.jdbc.SQLServerStatement.doExecuteStatement(Unknown Source)  

  5.     at com.microsoft.sqlserver.jdbc.SQLServerStatement$StatementExecutionRequest.executeStatement(Unknown Source)  

  6.     at com.microsoft.sqlserver.jdbc.CancelableRequest.execute(Unknown Source)  

  7.     at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeRequest(Unknown Source)  

  8.     at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeQuery(Unknown Source)  


使用以下代碼無效

Java代碼 複製代碼

  1. Statement stmt = con.createStatement(ResultSet.TYPE_FORWARD_ONLY,ResultSet.CONCUR_READ_ONLY);   

  2. stmt.setFetchSize(100);  

Java代碼  收藏代碼

  1. Statement stmt = con.createStatement(ResultSet.TYPE_FORWARD_ONLY,ResultSet.CONCUR_READ_ONLY);  

  2. stmt.setFetchSize(100);  


查文檔得知與sqlserver jdbc驅動的select Method有關。selectMethod分爲direct和cursor。當使用direct時,驅動會一次性載入所有結果集到jvm內存中,因此造成了out of memory;而使用cursor時,會在服務器端創建一個cursor,因此不會佔據客戶端的大量內存,辦法有兩種: 
[list=1]

  • 修改SQLServer2005 jdbc的URL: jdbc.url=jdbc:sqlserver://127.0.0.1;instanceName=ProductDB;databaseName=product_index;selectMethod=cursor
    這種方式會影響整個應用程序,可能引起其他普通情況的讀取性能下降。

  • 使用如下代碼

    Java代碼 複製代碼

    Java代碼  收藏代碼


    這種方式會造成SQLServer的API侵入,但不失爲一種更好的辦法。 

  1. Statement stmt = con.createStatement(SQLServerResultSet.TYPE_SS_SERVER_CURSOR_FORWARD_ONLY,ResultSet.CONCUR_READ_ONLY);  

  1. Statement stmt = con.createStatement(SQLServerResultSet.TYPE_SS_SERVER_CURSOR_FORWARD_ONLY,ResultSet.CONCUR_READ_ONLY);  


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章