解决了,当然,在这里发布后,让我大吃一惊...现在使用来自http://www.xerial.org/trac/Xerial/wiki/SQLiteJDBC#Download的不同驱动程序,不需要大量配置。

原来的问题在下面休息。

我正在鬼混包含OpenStreetMap数据的SQLite数据库,而JDBC遇到了一些麻烦。

下面的查询是我想用来快速获取用户位置的查询(数字来自我的测试数据,由Java代码添加)。

SELECT roads.nodeID, lat, lon
FROM roads
INNER JOIN nodes
ON roads.nodeID=nodes.nodeID
ORDER BY (ABS(lat - (12.598418)) + ABS(lon - (-70.043514))) ASC
LIMIT 1

“道路”和“节点”都包含大约130,000行。

这个特定的查询是最密集的查询之一,它只使用过两次,因此可以满足我的需求。使用Firefox SQLite时,它的执行时间约为281毫秒,但是在使用sqlitejdbc-v056的Java中,该过程需要12到14秒(处理器满负荷)。

有关如何解决此问题的任何线索?
public Node getNodeClosestToLocation(Location loc){
        try {
            Class.forName("org.sqlite.JDBC");
            Statement stat = conn.createStatement();
            String q = "SELECT roads.nodeID, lat, lon "+
            "FROM roads "+
            "INNER JOIN nodes "+
            "ON roads.nodeID=nodes.nodeID "+
            "ORDER BY (ABS(lat - ("+loc.getLat()+")) +
            ABS(lon - ("+loc.getLon()+"))) ASC "+
            "LIMIT 1";
            long start = System.currentTimeMillis();
            System.out.println(q);

            rs = stat.executeQuery(q);
            if(rs.next()) {
                System.out.println("Done. " + (System.currentTimeMillis() - start));

                return new Node(rs.getInt("nodeID"), rs.getFloat("lat"), rs.getFloat("lon"));
            }

        }
        catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }

最佳答案

在JDBC中选择语句查询时,如果使用不正确,它们可能会非常缓慢。几点:

  • 确保在表中索引正确的列。简单的行,例如:
  • Statement stat = connection.createStatement();
    stat.executeUpdate("create index {index_name} on orders({column_name});");
    stat.close();

    创建索引:http://www.w3schools.com/sql/sql_create_index.asp
  • 插入索引需要花费更长的时间,因为插入新记录时需要更新每个先前的索引。最好在执行所有insert语句(更好的性能)之后创建索引。索引列会影响插入性能,但选择性能会大大提高。
  • 更改JDBC驱动程序可能会有所帮助,但总的来说不是根本问题。另外,请确保您在纯模式下运行。至少从我注意到的情况来看,纯Java模式要慢得多。假设您正在使用SQLite JDBC,以下代码段将告诉您正在运行的模式。
  • System.out.println(String.format("%s mode", SQLiteJDBCLoader.isNativeMode() ? "native" : "pure-java"));
    在记录超过500K的数据库中,选择速度慢,我遇到了同样的问题。如果没有索引,我的应用程序的运行时间将为9.9天。现在,只需2分钟即可完成完全相同的操作。使用正确且经过优化的sql时,SQLite的速度非常快。

    07-24 09:49
    查看更多