第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問(wèn)題,去搜搜看,總會(huì)有你想問(wèn)的

從很大的表中獲取數(shù)據(jù)

從很大的表中獲取數(shù)據(jù)

寶慕林4294392 2021-05-19 10:18:55
我在MySQL數(shù)據(jù)庫(kù)中有一個(gè)非常大的表,在table中有2億條記錄Users。我使用JDBC進(jìn)行查詢(xún):public List<Pair<Long, String>> getUsersAll() throws SQLException {        Connection cnn = null;        CallableStatement cs = null;        ResultSet rs = null;        final List<Pair<Long, String>> res = new ArrayList<>();        try {            cnn = dataSource.getConnection();            cs = cnn.prepareCall("select UserPropertyKindId, login from TEST.users;");            rs = cs.executeQuery();            while (rs.next()) {                res.add(new ImmutablePair<>(rs.getLong(1), rs.getString(2)));            }            return res;        } catch (SQLException ex) {            throw ex;        } finally {            DbUtils.closeQuietly(cnn, cs, rs);        }    }接下來(lái),我處理結(jié)果:List<Pair<Long, String>> users= dao.getUsersAll();            if (CollectionUtils.isNotEmpty(users)) {                for (List<Pair<Long, String>> partition : Lists.partition(users, 2000)) {                    InconsistsUsers.InconsistsUsersCallable callable = new InconsistsUsers.InconsistsUsersCallable (new ArrayList<>(partition));                    processExecutor.submit(callable);                }            }但是由于該表非常大,并且全部都已卸載到內(nèi)存中,因此我的應(yīng)用程序崩潰并出現(xiàn)錯(cuò)誤:com.mysql.jdbc.exceptions.jdbc4.CommunicationsException:通信鏈接失敗從服務(wù)器成功接收到的最后一個(gè)數(shù)據(jù)包是105619毫秒之前。如何才能部分接收數(shù)據(jù)并按優(yōu)先級(jí)順序處理它們,以免一次將所有結(jié)果上傳到內(nèi)存中?創(chuàng)建游標(biāo)并將數(shù)據(jù)上傳到非阻塞隊(duì)列并在數(shù)據(jù)到達(dá)時(shí)對(duì)其進(jìn)行處理是可能的。如何才能做到這一點(diǎn)?
查看完整描述

3 回答

?
蕪湖不蕪

TA貢獻(xiàn)1796條經(jīng)驗(yàn) 獲得超7個(gè)贊

您應(yīng)該在幾個(gè)級(jí)別上處理此問(wèn)題:


JDBC驅(qū)動(dòng)程序訪存大小

JDBC有一個(gè)Statement.setFetchSize()方法,該方法指示從JDBC獲取行之前,JDBC驅(qū)動(dòng)程序?qū)㈩A(yù)取多少行。請(qǐng)注意,MySQL JDBC驅(qū)動(dòng)程序并未真正正確地實(shí)現(xiàn)此功能,但您可以設(shè)置setFetchSize(Integer.MIN_VALUE)為阻止它一次性獲取所有行。另請(qǐng)參閱此答案。


請(qǐng)注意,您還可以使用以下方法激活連接上的功能 useCursorFetch


你自己的邏輯

您不應(yīng)將整個(gè)用戶(hù)列表存儲(chǔ)在內(nèi)存中。您現(xiàn)在正在做的是從JDBC收集所有行,然后稍后使用來(lái)對(duì)列表進(jìn)行分區(qū)Lists.partition(users, 2000)。這是朝著正確的方向發(fā)展,但是您做的還不是很正確。相反,請(qǐng)執(zhí)行以下操作:


try (ResultSet rs = cs.executeQuery()) {

    while (rs.next()) {

        res.add(new ImmutablePair<>(rs.getLong(1), rs.getString(2)));

    }


    // Process a batch of rows:

    if (res.size() >= 2000) {

        process(res);

        res.clear();

    }

}


// Process the remaining rows

process(res);

此處的重要信息是不加載內(nèi)存中的所有行,然后分批處理它們,而是在從JDBC流傳輸行時(shí)直接處理它們。


查看完整回答
反對(duì) 回復(fù) 2021-05-19
?
慕田峪9158850

TA貢獻(xiàn)1794條經(jīng)驗(yàn) 獲得超8個(gè)贊

而不是Java端的Lists.partition(users,2000),您應(yīng)該將每個(gè)請(qǐng)求的mysql結(jié)果集限制為2000。

select UserPropertyKindId, login from TEST.users limit <offset>, 2000;

更新:正如Raymond Nijland在下面的評(píng)論中提到的,如果偏移量太大,則查詢(xún)速度可能會(huì)大大降低。

一種解決方法可能是使用偏移量,而不是使用偏移量,引入where語(yǔ)句,例如where id> last_user_id。

由于@All_safe在下面進(jìn)行了注釋?zhuān)虼瞬淮嬖谧詣?dòng)增量ID,因此另一個(gè)針對(duì)較大偏移量的解決方法是:僅在子查詢(xún)中獲取主鍵,然后再聯(lián)接回主表。這將強(qiáng)制mysql不執(zhí)行早期行查找,這是大偏移量限制的主要問(wèn)題。

但是您的原始查詢(xún)僅獲取主鍵列,我認(rèn)為早期行查找不適用。


查看完整回答
反對(duì) 回復(fù) 2021-05-19
?
DIEA

TA貢獻(xiàn)1820條經(jīng)驗(yàn) 獲得超3個(gè)贊

我遇到了類(lèi)似的情況。我正在從一個(gè)MySQL數(shù)據(jù)庫(kù)中讀取數(shù)據(jù),并將其復(fù)制到MS SQL Server數(shù)據(jù)庫(kù)中。不是2億,每天只有400萬(wàn)。但是我在通信鏈接失敗時(shí)也遇到了同樣的錯(cuò)誤消息。我可以通過(guò)設(shè)置PreparedStatement.setFetchSize(Integer.MIN_VALUE);的fetchsize來(lái)解決它。因此,通信鏈接故障消失了。我知道,這不能解決您的列表問(wèn)題。


查看完整回答
反對(duì) 回復(fù) 2021-05-19
  • 3 回答
  • 0 關(guān)注
  • 186 瀏覽
慕課專(zhuān)欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢(xún)優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)