Java 与FirefoxDB管理器相比,JDBC选择速度非常慢

Java 与FirefoxDB管理器相比,JDBC选择速度非常慢,java,sql,sqlite,jdbc,Java,Sql,Sqlite,Jdbc,解决了,当然,在发布到这里之后,我想到了。。。现在使用不同的驱动程序不需要大量配置 原来的问题在下面休息 我在玩弄一个包含OpenStreetMap数据的SQLite数据库,而我在使用JDBC时遇到了一些问题 下面的查询是我想用来快速获得一个接近我的用户位置的位置(数字来自我的测试数据,由java代码添加) “道路”和“节点”都包含大约130000行 这个特定的查询是最密集的buyt之一,它只使用了两次,所以应该可以满足我的需要。当使用Firefox SQLite时,它的执行时间约为281毫秒

解决了,当然,在发布到这里之后,我想到了。。。现在使用不同的驱动程序不需要大量配置

原来的问题在下面休息


我在玩弄一个包含OpenStreetMap数据的SQLite数据库,而我在使用JDBC时遇到了一些问题

下面的查询是我想用来快速获得一个接近我的用户位置的位置(数字来自我的测试数据,由java代码添加)

“道路”和“节点”都包含大约130000行

这个特定的查询是最密集的buyt之一,它只使用了两次,所以应该可以满足我的需要。当使用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;
    }
使用a可能会给您带来稍好的性能,但没有这里描述的那么大

也许Firefox SQLite正在使用一些提示。您可以尝试获取执行计划,以查看查询在哪里进行了艰苦的工作,并在需要时创建一些索引


您是否尝试记录任何计时信息以确保它没有获得昂贵的连接?

在JDBC中,当涉及select语句查询时,如果没有正确使用它们,它们可能会非常缓慢。有几点:

  • 确保为表中的正确列编制索引。简单的一行,例如:
  • Statement stat=connection.createStatement()
    stat.executeUpdate(“在订单({column_name})上创建索引{index_name};”)
    stat.close()

    创建索引:

  • 插入索引需要更长的时间,因为插入新记录时需要更新以前的每个索引。创建索引最好在执行所有insert语句之后完成(性能更好)。索引列的插入性能受到影响,但选择性能要快得多

  • 更改JDBC驱动程序可能会略有帮助,但总体而言,这不应该是根本问题。还要确保您在本机模式下运行。纯java模式要慢得多,至少我注意到了这一点。假设您使用的是SQLite JDBC,下面的代码段将告诉您正在运行的模式

  • System.out.println(String.format(“%s mode”,SQLiteJDBCLoader.isNativeMode()?“native”:“纯java”)


    在一个有超过500K条记录的数据库中,我遇到了同样的问题,即选择缓慢。如果我没有索引,我的应用程序的运行时间应该是9.9天。现在做同样的事情需要2分钟的时间。当使用适当和优化的sql时,SQLite的速度非常快。

    为什么sqllite查询与浏览器相关?这可能是应用程序中的其他组件吗?很抱歉造成混淆:这只是为了证明查询本身不应该太慢,因为另一个应用程序(本例中是Firefox浏览器的SQLite DB Manager插件)的速度要快得多。你可以看到我在计时,这是一个非常“年轻”的项目,只有一个线程在运行。你确定使用相同数量的数据、相同的查询和相同的结果吗?并且都是从同一内存存储器(RAM/HDD/SDD)中读取的?如果在FF测试中从RAM读取100行,在Java的HDD中读取130000行,这就不足为奇了:)否则,这可能是Java实现中的一个错误,只是为了比较,请尝试:选择(ABS(lat-(12.598418))+ABS(lon-(-70.043514))作为距离,roads.nodeID,lat,lon FROM roads内部连接roads上的节点。nodeID=nodes.nodeID ORDER BY 1 ASC LIMIT 1同样,如果一行执行两次相同的查询,则第二次执行会更快,因为服务器缓存了数据
    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;
        }