【发布时间】:2012-04-16 07:37:32
【问题描述】:
已解决,当然在这里发布后它击中了我...现在使用来自 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;
}
【问题讨论】:
-
sqllite查询怎么跟浏览器有关系?应用程序中的其他组件可以吗?
-
抱歉造成混淆:这只是为了证明查询本身不应该很慢,因为另一个应用程序(在这种情况下是 Firefox 浏览器的 SQLite DB Manager 插件)做了很多快点。你可以看到我在做计时,这是一个非常“年轻”的项目,只有一个线程在运行。
-
你确定你使用相同数量的数据,相同的查询并且结果相同吗?两者都是从同一个内存存储中读取的 - RAM / HDD / SDD?如果你从 RAM 中读取 100 行用于 FF 测试,从 HDD 中读取 130 000 行用于 Java,那就不足为奇了 :) 否则,这可能是 Java 实现中的一个错误
-
为了比较,请尝试:SELECT (ABS(lat - (12.598418)) + ABS(lon - (-70.043514))) as distance, road.nodeID, lat, lon FROM road Roads.nodeID=nodes.nodeID ORDER BY 1 ASC LIMIT 1 上的 INNER JOIN 节点
-
此外,如果您连续两次执行相同的查询,第二次执行会更快,因为服务器缓存了数据