JDBC讀取mysql的數據的效率問題

背景

這邊我們做了一個產品的小功能,把mysql的數據拉取到hdfs上來

代碼實現

代碼很簡單,就是簡單的JDBC

long start = System.currentTimeMillis();
PreparedStatement preparedStatement = connection.prepareStatement("select * from ceshi");
ResultSet resultSet = preparedStatement.executeQuery();
ResultSetMetaData metaData = resultSet.getMetaData();
int columnCount = metaData.getColumnCount();
long end = System.currentTimeMillis();
System.out.println("------"+Thread.currentThread()+"獲取數據消耗時間"+(end-start)/1000);

讀取數據,然後hdfs的IO流寫入到hdfs上面。但是我發現在讀取數據的時候會出現卡頓的情況。(我這邊數據量大約100W),我打印了日誌,發現在接收數據的時候,耗時大約在10秒,
後來開始查資料發現mysql查詢的機制是jdbc默認的讀取數據的時候,會將要查詢的數據一次性讀到內存中,再通過resultSet循環讀取出來。

調研了下發現可以通過JDBC 流的方式來讀取數據,這種方式可以將讀取出來的每一條數據查詢到客戶端,再執行insert操作,這樣機器負載就會輕很多。
相關源碼如下

    /**
     * We only stream result sets when they are forward-only, read-only, and the
     * fetch size has been set to Integer.MIN_VALUE
     * 
     * @return true if this result set should be streamed row at-a-time, rather
     *         than read all at once.
     */
    protected boolean createStreamingResultSet() {
        return ((this.query.getResultType() == Type.FORWARD_ONLY) && (this.resultSetConcurrency == java.sql.ResultSet.CONCUR_READ_ONLY)
                && (this.query.getResultFetchSize() == Integer.MIN_VALUE));
    }

然後之前的代碼如下

long start = System.currentTimeMillis();
PreparedStatement preparedStatement = connection.prepareStatement("select * from ceshi",ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
preparedStatement.setFetchSize(Integer.MIN_VALUE);
ResultSet resultSet = preparedStatement.executeQuery();
ResultSetMetaData metaData = resultSet.getMetaData();
int columnCount = metaData.getColumnCount();
long end = System.currentTimeMillis();
System.out.println("------"+Thread.currentThread()+"獲取數據消耗時間"+(end-start)/1000);

然後就會發現獲取數據不會消耗時間,大大提升了效率。
順便說一下 不添加 這兩個參數ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY 也可以,因爲mysql connection.prepareStatement(sql)中就默認設置這兩個參數的。感興趣的可以直接看下源碼。
所以爲了方便也可以直接設置

preparedStatement.setFetchSize(Integer.MIN_VALUE);

參考資料:https://blog.csdn.net/zhouxukun123/article/details/83476715

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