Загрузка x строк из базы данных за раз, их отображение, загрузка следующих x строк и т. Д. - PullRequest
1 голос
/ 27 марта 2019

У меня есть база данных с несколькими таблицами, каждая из которых содержит миллионы строк данных. В моем приложении Java моя задача - отображать определенные данные из определенных таблиц в зависимости от аргументов, которые я получаю от пользователя. Я успешно смог загрузить все эти данные одновременно, но когда есть 10 миллионов строк, это занимает много времени. Я узнал о connection.setAutoCommit(false) и statement.setFetchSize(x), но, похоже, они не работают.

public static int getTableResults(Result_Controller okno){
    int i = 0;
    try {
        Connection con = getConnection();
        con.setAutoCommit(false);

        String query = "SELECT h.\"Nazov hotela\", k.\"Nazov krajiny\", m.\"Nazov mesta\", h.\"Adresa hotela\", h.\"Hviezdicky\", p.\"Cena pobytu\", i.\"Typ izby\", h.\"Pocet izieb\" " +
                "FROM hotel h " +
                "inner JOIN izba i ON i.\"ID hotela\" = h.\"ID hotela\" " +
                "inner JOIN krajina k ON k.\"ID krajiny\" = h.\"ID krajiny\" " +
                "inner JOIN mesto m ON m.\"ID mesta\" = h.\"ID mesta\" " +
                "inner JOIN pobyt p ON p.\"ID hotela\" = h.\"ID hotela\" " +
                "WHERE h.\"Nazov hotela\" = ? " +
                "AND k.\"Nazov krajiny\" = ? " +
                "AND h.\"Hviezdicky\" = ? " +
                "AND i.\"Pocet posteli\" >= ? " +
                "AND p.\"Cena pobytu\" <= ? " +
                "ORDER BY h.\"Nazov hotela\"";

        PreparedStatement pst = con.prepareStatement(query, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
        pst.setFetchSize(150);

        pst.setString(1, okno.getText_nazov().getText());
        pst.setString(2, (String) okno.getKrajina().getValue());

        int pocet_hviezdiciek = Integer.parseInt((String) okno.getHviezdicky().getValue());
        pst.setInt(3, pocet_hviezdiciek);

        int pocet_osob = Integer.parseInt((String) okno.getOsoby().getValue());
        pst.setInt(4, pocet_osob);

        double cena_pobytu = Double.parseDouble(okno.getText_cena().getText());
        pst.setDouble(5, cena_pobytu);

        ResultSet rs = pst.executeQuery();
        System.out.println(pst);

        while (rs.next()) {
            okno.getOblist().add(new Vysledok_hladania(rs.getString("Nazov hotela"),
                    rs.getString("Nazov krajiny"),
                    rs.getString("Nazov mesta"),
                    rs.getString("Adresa hotela"),
                    rs.getInt("Hviezdicky"),
                    rs.getDouble("Cena pobytu"),
                    rs.getString("Typ izby"),
                    rs.getInt("Pocet izieb")));

            System.out.println(i++);
        }
        okno.getTable().setItems(okno.getOblist());
    } catch (SQLException ex) {
        Logger.getLogger(Result_Controller.class.getName()).log(Level.SEVERE, null, ex);
    }
return i;
}

В целом, я хочу получить эти результаты и отображать их партиями, а не все одновременно.

1 Ответ

0 голосов
/ 28 марта 2019

Вы не показываете план выполнения, но проблема должна быть ORDER BY.PostgreSQL необходим полный результат, прежде чем он сможет начать сортировку.

Вы можете получить план «быстрого запуска» с вложенным циклом, если создадите следующий индекс:

CREATE INDEX ON hotel ("Nazov hotela");

Кроме того, у вас должен быть индекс для условий соединения (столбцы идентификаторов) для всех других таблиц:

CREATE INDEX ON izba ("ID hotela");
CREATE INDEX ON krajina ("ID krajiny");
CREATE INDEX ON mesto ("ID mesta");
CREATE INDEX ON pobyt ("ID hotela");
...