HSQLDB 索引不一致

Posted

技术标签:

【中文标题】HSQLDB 索引不一致【英文标题】:HSQLDB index inconsistency 【发布时间】:2012-09-27 16:09:37 【问题描述】:

我在我们的 java 项目中遇到了 HSQLDB 的奇怪行为。非常简单的查询返回不一致的结果。我将问题追溯到某些表的索引不是最新的。不幸的是,我既不是 SQL 专家,也不是处理 java 数据库的专家。

HSQLDB 版本是 2.2.8。我试图更新到 2.2.9 但这没有帮助。

我们的数据库非常简单。它包含几个独立的表。他们之间没有任何关系。每个表都配备了索引,其中一个是结合了几列的唯一索引。这是一个例子:

CREATE CACHED TABLE PUBLIC.MYTABLE(
  A BIGINT DEFAULT -9999 NOT NULL,
  B BIGINT DEFAULT -9999 NOT NULL,
  C NUMERIC(12,7) DEFAULT -9999.0000000 NOT NULL,
  D INTEGER DEFAULT -9999 NOT NULL);

CREATE INDEX IDX1 ON PUBLIC.MYTABLE( A );
CREATE INDEX IDX2 ON PUBLIC.MYTABLE( B );
CREATE INDEX IDX3 ON PUBLIC.MYTABLE( C );

CREATE UNIQUE INDEX MYTABLE_PRIMARY_KEY ON PUBLIC.MYTABLE( A, B );

我们通常从 java 程序中插入行和查询表,从不更新现有的行。插入操作如下所示:

Connection con = ...; // get connection from 
PreparedStatement stmt;

con.setAutoCommit( false );

stmt = this.con.prepareStatement( 
    String.format( 
       "insert into %s values (?,?,?,?)", "MYTABLE"));

stmt.setLong(1, data1);
stmt.setLong(2, data2);
stmt.setDouble(3, data3);
stmt.setInt(4, data4);

stmt.addBatch()

我们在其他地方执行批处理

stmt.executeBatch();
stmt.clearBatch();
con.commit();

代码在循环中执行,之后我们用适当的方法关闭语句和连接。此外,连接 url 末尾有“shutdown=true”,所以我们希望数据库能够正确关闭。

正如我前面提到的,我在 SQL 查询时注意到了这个问题,例如

SELECT COUNT(*) FROM MYTABLE

开始返回不合理的结果,例如它只返回了预期行数的大约一半。作为一项实验,我从表中删除了唯一索引,并且所有查询都正常工作。这就是为什么我认为由于某种原因索引在插入时没有正确更新。查看索引的线索来自在留言板和论坛上搜索和阅读 cmets。

如Disable and rebuild an index in HSQLDB中所述,我使用了

SHUTDOWN COMPACT

并且修复了我们数据库中的所有表,所有数据都在那里,所有查询都返回正确的结果。我怀疑该问题的作者遇到了与我类似的问题。

好的,我的数据是安全的,所以我想了解并纠正问题的根源。

索引是否应该在插入时更新?或者这是一个错误的假设,我们每次更新数据库时都需要执行 SHUTDOWN COMPACT?

多列的唯一索引是否可能是问题的根源?

如果有任何建议或指示,我将不胜感激。

【问题讨论】:

【参考方案1】:

索引总是在插入/删除/更新时更新。不需要为此目的执行 SHUTDOWN COMPACT。

不清楚是什么导致了不一致。如果能用虚拟数据复现,那就给HSQLDB项目提交一个测试用例,调查一下。

【讨论】:

感谢您的建议。我将尝试在虚拟数据上重现该问题。 尝试使用虚拟数据重现该问题,但失败了。一切正常。还检查了几个部署的数据库,它们都很好。该问题仅出现在我用于在计算机上进行测试的两个数据库中。我认为在调试应用程序时可能有一些特殊情况破坏了索引。 我仍在尝试找出问题的根源。一件事是使用停止按钮从 NetBeans IDE 终止进程存在问题。它在Bug 22641 有完整的描述。简而言之,使用停止按钮不会调用关闭挂钩,我的数据库关闭代码就在那里。而且我经常使用那个按钮,所以很多时候数据库都没有正确关闭。

以上是关于HSQLDB 索引不一致的主要内容,如果未能解决你的问题,请参考以下文章

为啥标签与 pandas、itertools 和 numpy 索引不一致?

MySQL字符集不一致导致索引失效

MySQL字符集不一致导致索引失效

将 CSV 索引到不一致的样本数量以进行逻辑回归

C# 中插入符号位置、字符串长度和匹配索引的不一致

不同时期的不一致索引只得到一种类型