Выполнить запрос к таблице, содержащей миллиарды записей

Я хочу получить какую-либо запись (это может быть 50 100 или что-то еще, что настраивается пользователем) из базы данных без использования предложения limit, потому что наше приложение может работать с несколькими базами данных, такими как mysql,oracle,mssql,db2....

я сделал следующее решение

package com.test;

import java.sql.Connection;
import java.sql.Statement;
import java.sql.ResultSet;
import java.sql.DriverManager;
import java.util.Date;

public class BatchRetrieveTest extends Object {
    private static final int FETCH_SIZE = 10;

    public BatchRetrieveTest() {
    }

    public static void main(String[] args) {
        BatchRetrieveTest batchRetrieveTest = new BatchRetrieveTest();
        batchRetrieveTest.test();
    }

    void test() {
        Connection conn = null;
        Statement stmt2 = null;
        Date start = null;
        Date end = null;
        int i = 0;
        try {
            conn = DriverManager.getConnection(
                    "jdbc:mysql://localhost:3306/test",
                    "root", "root");
            stmt2 = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
                    ResultSet.CONCUR_READ_ONLY);
            conn.setAutoCommit(false);
            stmt2.setFetchSize(FETCH_SIZE);
            stmt2.setPoolable(true);
            start = new Date();
            System.out.println(new Date() + "second execute start"
                    + new Date().getTime());
            ResultSet rs2 = stmt2
                    .executeQuery("SELECT * FROM sample_final_attendance limit 1000");

            end = new Date();
            System.out.println(new Date() + "*************second execute end"
                    + (end.getTime() - start.getTime()));
            rs2.absolute(200000);
            i = 0;
            while (rs2.next()) {
                if (i++ > 100) {
                    break;
                }
            }
            rs2.close();
            stmt2.close();
            end = new Date();
            System.out.println(new Date() + "second read end"
                    + (end.getTime() - start.getTime()));
            conn.close();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                stmt2.close();
                conn.close();
            } catch (Exception e) {
            }
        }
    }
}

Здесь таблица sample_final_attendance содержит 15 столбцов и 3,2 миллиона записей, а для выполнения этой программы требуется 2 ГБ памяти и 47 секунд времени выполнения.

здесь интересно, что если какая-то таблица имеет миллиарды записей, она не может быть выполнена

также я использовал setFetchSize как и предполагалось, но проблема та же

пожалуйста, предложите какое-то решение

заранее спасибо

2 ответа

Мы установили setMaxRow(int numOfRow) в объекте Statement, это ограничит число строк, генерируемых объектом Statement, и просто проигнорирует оставшиеся.

Посмотрите на документ.

Ну, как понял ASFAIK, проблема больше связана с обработкой данных в хранилище полиглотов. Если вы думаете, вам нужно разрешить одно и то же во всех случаях независимо от типа базы данных - один общий подход заключается в создании обслуживающего уровня.

Обслуживающий слой может быть кеш-библиотекой или даже созданной вами картой карт. Не пытайтесь запрашивать базу данных с большим количеством записей одновременно, вместо этого приносите данные в виде пакетов и сохраняйте их как пул pojos. По требованию пользователя вы можете обслуживать данные с обслуживающего слоя.

Вы можете использовать memcache или hazlecast или многие другие библиотеки кеша, которые могут быть напрямую интегрированы с базами данных. Я действительно не знаю, насколько сложна ваша ситуация. Я сделал предложение. Это составляет сетку данных, которая может быть заполнена данными из любых баз данных в фоновом режиме.

Другие вопросы по тегам