繁体   English   中英

与Firefox DB管理器相比,JDBC SELECT非常慢

[英]JDBC SELECT very slow in comparison to Firefox DB manager

解决了 ,当然在发布后,它打了我...现在使用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

'roads'和'nodes'都包含大约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中的select语句查询时,如果它们没有被正确使用,它们会非常缓慢。 几点:

  1. 确保索引表中正确的列。 一个简单的行,如:

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

  1. 使用索引插入时间更长,因为每次插入新记录时都需要更新先前的索引。 在执行所有insert语句(性能更好)之后,最好先创建索引。 索引列会影响插入性能,但选择性能会明显加快。

  2. 更改JDBC驱动程序可能会有所帮助,但总体上不应该是潜在的问题。 还要确保您以纯模式运行。 Pure-java模式明显变慢,至少从我注意到的情况来看。 假设您正在使用SQLite JDBC,以下代码段将告诉您正在运行的模式。

System.out.println(String.format("%s mode", SQLiteJDBCLoader.isNativeMode() ? "native" : "pure-java"));

我在历史记录超过500K的数据库中选择速度慢,遇到了同样的问题。 如果我没有编入索引,我的申请的运行时间将为9.9天。 现在这是一个超快的2分钟做同样的事情。 当使用正确和优化的sql时,SQLite非常快。

使用PreparedStatement可能会给你带来稍微好一点的性能,但这里没有描述其大小。

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM