【发布时间】:2012-03-31 23:11:57
【问题描述】:
我有一个名为history_point 的简单表,其中包含以下列:
-
id- 整数PK -
device_id- 整数 -
registered- 时间戳 -
double_value- 双人间 -
channel- 整数 -
type- VARCHAR(100) -
int_value- 整数
该表还为以下列组合定义了索引:
iddevice_idregisteredchannel-
device_id,channel,registered
该表包含大约 200000 行。我使用下面的 Java 代码运行查询。
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class JdbcMain {
public static void main(String[] args) throws Exception {
Class.forName("org.hsqldb.jdbcDriver");
Connection con = DriverManager.getConnection("jdbc:hsqldb:file:db/homeki.db;ifexists=true");
Statement stmt = con.createStatement();
long start = System.currentTimeMillis();
ResultSet rs = stmt.executeQuery("<SQL query goes here>");
if (rs.next()) {
System.out.println("Registered: " + rs.getDate("registered"));
}
long dur = System.currentTimeMillis() - start;
System.out.println("Took " + dur + " ms.");
stmt.execute("SHUTDOWN");
con.close();
}
}
当我运行查询 SELECT * FROM history_point WHERE device_id = 3 AND channel = 0 LIMIT 1 时,大约需要 5 毫秒。如果我运行查询SELECT * FROM history_point ORDER BY registered DESC LIMIT 1,也需要大约 5 毫秒。 但是,如果我运行查询SELECT * FROM history_point WHERE device_id = 3 AND channel = 0 ORDER BY registered DESC LIMIT 1,大约需要 1000 毫秒!
考虑到他们在http://www.hsqldb.org/doc/1.8/guide/ch02.html#N1033B 上所说的话,我想这可以理解,“HSQLDB 不使用索引来改进查询结果的排序”(顺便说一句,这对我来说听起来很奇怪)。
然而,如果我使用 Eclipse Data Tools Platform 的 SQL Scrapbook 在 Eclipse 中运行最后一个查询,它会在大约 5 毫秒内执行。我使用 SQL Scrapbook 向它提出的任何查询都会在大约 5 毫秒内执行。这是为什么?它们都使用相同的 JDBC 驱动程序和相同的数据库。
history_point 中有大约 25000 行,device_id = 3 和 channel = 0,如果这很重要的话。
我使用的连接字符串是jdbc:hsqldb:file:db/mystorage.db。该表被创建为CACHED 表(所有数据都存储在磁盘上)。
谁能解释一下?
提前致谢!
【问题讨论】:
-
哪个版本的 HSQLDB?如果您使用的是最新版本,请参考在线版本 2.x 指南。
-
你是绝对正确的。我使用 HSQLDB 2.2.8,并且正在查看 1.8 的指南。这是 HSQLDB 2.X 的相同部分:hsqldb.org/doc/2.0/guide/sqlgeneral-chapt.html#sgc_index_speed。似乎没有相同的限制(对 ORDER BY 使用索引)。但问题仍然存在..