一次从数据库加载x行,显示它们,然后加载接下来的x行,依此类推

时间:2019-03-27 13:10:35

标签: java postgresql jdbc pagination

我有一个包含多个表的数据库,每个表都有数百万行数据。在我的Java应用程序中,我的任务是根据从用户那里获得的参数显示某些表中的某些数据。我已经成功地能够一次加载所有这些数据,但是当有1000万行时,这将花费很长时间。我发现了有关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 :(得分:0)

您没有显示执行计划,但是问题必须是ORDER BY。 PostgreSQL需要完整的结果才能开始排序。

如果创建以下索引,则可以通过嵌套循环获得“快速启动”计划:

CREATE INDEX ON hotel ("Nazov hotela");

此外,您需要为所有其他表上的连接条件(ID列)建立索引:

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