JDBC 默認將整個 ResultSet 緩存到客戶端內存(mysql_store_result 行為),大查詢需等待全量傳輸才能讀取第一行。MySQL Connector/J 提供 enableStreamingResults() 切換到流式模式(mysql_use_result),實現「首行秒出、逐行拉取」。
mysql -q(--quick)可流式輸出,首行毫秒級返回。setFetchSize(0) 觸發全量緩存,大結果集 OOM 或首行延遲極高。Statement.setFetchSize(1) 單獨設置在 MySQL 驅動中**無效**,需配合流式模式。import com.mysql.jdbc.Statement; // 驅動具體實現類
// 獲取驅動專用 Statement
Statement stmt = (Statement) conn.createStatement();
// 關鍵:啟用流式結果集
stmt.enableStreamingResults();
// 可選:配合 fetchSize=1 進一步減少客戶端緩存
stmt.setFetchSize(1);
// 執行大查詢
ResultSet rs = stmt.executeQuery("SELECT * FROM huge_table WHERE ...");
// 首行近實時返回,後續逐行網絡拉取
while (rs.next()) {
// 處理數據
}
// 用完必須關閉結果集和語句,釋放服務端資源
rs.close();
stmt.close();
// 或重置為默認緩存模式
stmt.disableStreamingResults();
| 模式 | C API 對應 | 行為 | 適用場景 |
|---|---|---|---|
| 默認緩存 | mysql_store_result | 全量拉取到客戶端內存,隨機訪問 | 小/中結果集、需多游標 |
| 流式 | mysql_use_result | 服務端保留結果,客戶端逐行拉取,只能順序讀取 | 大結果集、流式處理、首行快速響應 |
rs.absolute()、rs.previous()、rs.last() 等隨機定位。com.mysql.cj.jdbc.Statement。| 模式 | 首行耗時 | 內存佔用 | 網絡模式 |
|---|---|---|---|
| 默認緩存 | ~20 秒 | ~2 GB (客戶端) | 突發大包 |
| 流式 + fetchSize=1 | < 1 秒 | ~MB 級 (客戶端) | 均勻小包 |
try-with-resources 確保資源釋放。LIMIT offset, size)或臨時表。掌握 enableStreamingResults(),讓 Java 應用輕松應對百萬級導出、報表、ETL 場景的首屏加速需求。