搜尋

首頁  >  問答  >  主體

了解 SQL Server JDBC 驅動程式中 Statement.setFetchSize(nSize) 方法的功能

<p>我有一個非常大的表,每天都有數百萬筆記錄,每天結束時我都會提取前一天的所有記錄。我這樣做是這樣的:</p> <pre class="brush:php;toolbar:false;">String SQL = "select col1, col2, coln from mytable where timecol = yesterday"; 州.executeQuery(SQL);</pre> <p>問題是這個程式需要大約 2GB 內存,因為它將所有結果放入內存中然後對其進行處理。 </p> <p>我嘗試設定 <code>Statement.setFetchSize(10)</code> 但它從作業系統中取得完全相同的內存,沒有任何區別。我為此使用<em>Microsoft SQL Server 2005 JDBC 驅動程式</em>。 </p> <p>是否有任何方法可以像 Oracle 資料庫驅動程式一樣以小塊形式讀取結果,當執行查詢時僅顯示幾行,並且當您向下捲動時會顯示更多結果? </p>
P粉463811100P粉463811100475 天前573

全部回覆(1)我來回復

  • P粉186897465

    P粉1868974652023-08-28 10:02:56

    在 JDBC 中,setFetchSize(int) 方法對於 JVM 內的效能和記憶體管理非常重要,因為它控制從 JVM 到資料庫的網路呼叫數量以及對應的資料量。用於結果集處理的 RAM。

    本質上,如果呼叫 setFetchSize(10) 並且驅動程式忽略它,則可能只有兩個選項:

    1. 嘗試使用不同的 JDBC 驅動程式來支援取得大小提示。
    2. 檢視 Connection 上特定於驅動程式的屬性(建立 Connection 實例時的 URL 和/或屬性對應)。

    RESULT-SET 是為回應查詢而在資料庫上編組的行數。 ROW-SET 是每次從 JVM 呼叫到 DB 時從 RESULT-SET 中提取的行塊。 這些呼叫的數量以及處理所需的 RAM 取決於 fetch-size 設定。

    因此,如果 RESULT-SET 有 100 行且 fetch-size 為 10, 在任何給定時間,都會有 10 個網路呼叫來檢索所有數據,使用大約 10*{row-content-size} RAM。

    預設的 fetch-size 是 10,這個值相當小。 在發布的案例中,驅動程式似乎忽略了獲取大小設置,在一次呼叫中檢索所有資料(需要大量 RAM,最佳最小網路呼叫)。

    ResultSet.next() 下發生的情況是,它實際上並沒有從 RESULT-SET 一次取得一行。它從(本地)ROW-SET 獲取該數據,並在本地客戶端上的數據耗盡時從伺服器獲取下一個 ROW-SET(不可見)。

    所有這些都取決於驅動程序,因為設定只是一個“提示”,但在實踐中我發現這就是許多驅動程式和資料庫的工作原理(在許多版本的 Oracle、DB2 和 MySQL 中得到驗證)。

    回覆
    0
  • 取消回覆