Java プロジェクトで HSQLDB の奇妙な動作に遭遇しました。非常に単純なクエリが一貫性のない結果を返しました。一部のテーブルのインデックスが最新ではないという問題を追跡しました。残念ながら、私は SQL の専門家でも、Java からデータベースを扱う専門家でもありません。
HSQLDB のバージョンは 2.2.8 です。2.2.9 に更新しようとしましたが、役に立ちませんでした。
私たちのデータベースはとてもシンプルです。いくつかの独立したテーブルが含まれています。それらの間に関係はありません。各テーブルにはインデックスが装備されており、そのうちの 1 つは複数の列を組み合わせた一意のインデックスです。次に例を示します。
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
予想される行数の約半分しか返されないなど、不当な結果が返されるようになりました。実験として、テーブルから一意のインデックスを削除すると、すべてのクエリが正しく機能しました。これが、何らかの理由で挿入時にインデックスが適切に更新されていないと思う理由です。インデックスを調べる手がかりは、メッセージ ボードやフォーラムのコメントをグーグル検索して読むことから得られました。
使用したHSQLDBでインデックスを無効にして再構築するで説明されているように
SHUTDOWN COMPACT
データベース内のすべてのテーブルが修復され、すべてのデータがそこにあり、すべてのクエリが正しい結果を返します。その質問の作者は私のものと同様の問題を抱えていたと思います。
わかりました。私のデータは安全なので、問題の原因を理解し、修正したいと思います。
インデックスは挿入時に更新されるはずですか? それとも、これは誤った仮定であり、データベースを更新するたびに SHUTDOWN COMPACT を実行する必要があるのでしょうか?
複数の列に対する一意のインデックスが問題の原因である可能性はありますか?
提案や指示をいただければ幸いです。