H2Databaseを追っかけていたりしたブログ

H2 database のリリースノートを読んだりとか。

Version 1.2.134 (2010-04-23)

1.2.134が出ました。

今回もこまごまと機能追加が多いリリースになっています。以下気になった点をいくつか。

  • システムプロパティにh2.analyzeAutoが追加。この行数を超える更新が発生(テーブルごと?)すると、自動でanalyzeが実行される。ただし、現在はデフォルト設定で0(無効)。1.3系から2000に設定される予定。
  • EXPLAIN ANALYZEステートメントが追加。実際に行スキャンされた件数を表示する事ができるようになりました。ちょっと試してみました。scanCountが、scanされた行数のようです。ただ、5000行のとき5001行になっているのが謎。テーブルに1行しかないときは、1だったのに。
create table staff (id int not null primary key, lname varchar, fname varchar, item_id int);
insert into staff select x, 'lname'||x, 'fname'||x, mod(x,2) from system_range(1,5000);
(Update count: 5000, 175 ms)
sql> explain analyze select * from staff;
PLAN
SELECT STAFF.ID, STAFF.LNAME, STAFF.FNAME, STAFF.ITEM_ID
FROM PUBLIC.STAFF /* PUBLIC.STAFF.tableScan */ /* scanCount: 5001 */
(1 row, 9 ms)
sql> explain analyze select * from staff where item_id = 0;
PLAN
SELECT STAFF.ID, STAFF.LNAME, STAFF.FNAME, STAFF.ITEM_ID
FROM PUBLIC.STAFF /* PUBLIC.STAFF.tableScan */ /* scanCount: 5001 */
WHERE ITEM_ID = 0
(1 row, 10 ms)
sql> analyze;   
(Update count: 0, 67 ms)
sql> explain analyze select * from staff where item_id = 0;
PLAN
SELECT STAFF.ID, STAFF.LNAME, STAFF.FNAME, STAFF.ITEM_ID
FROM PUBLIC.STAFF /* PUBLIC.STAFF.tableScan */ /* scanCount: 5001 */
WHERE ITEM_ID = 0
(1 row, 7 ms)
sql> create index ind_item on staff(item_id);
(Update count: 0, 28 ms)
sql> explain analyze select * from staff where item_id = 0;
PLAN
SELECT STAFF.ID, STAFF.LNAME, STAFF.FNAME, STAFF.ITEM_ID
FROM PUBLIC.STAFF /* PUBLIC.IND_ITEM: ITEM_ID = 0 */ /* scanCount: 2501 */
WHERE ITEM_ID = 0
(1 row, 14 ms)
  • merge文で、外部キーをチェック漏れしていたのが直っています。えええ、さらっと書いてあるけど強烈なバグですね....。確かに下記のsqlを試してみると、1.2.133は最後のmerge文が成功します....。1.2.134からは、正しく参照整合性制約に引っかかって失敗します...。
create table type_mst(id int not null primary key, name varchar);
create table item(id int not null primary key, type int not null,
foreign key(type) references type_mst(id));

insert into type_mst values (1, 'typeA');
insert into type_mst values (2, 'typeB');

insert into item values (1,1);
insert into item values (2,3);
merge into item values (2,3);
  • REPLACE関数の挙動が変わっています。REPLACE関数は REPLACE(元文字列, 変換前文字, 変換後文字)で、変換後文字が省略可能(その場合、変換前文字があったら削除)。1.2.133では、変換後文字をnullにしていた場合も、変換前文字を削除する動きになっていましたが、1.2.134では、いずれかの引数がnullだと返りもnullになっています。
  • distinctとorder byが組み合わされて使われた場合に、indexによるsortが効かなくなっていたのが直っています(下記のsqlはGoogleGroupの投稿を元にちょっと変更) 1.2.134では、index sortedとなります。
DROP TABLE IF EXISTS test; 
CREATE TABLE test ( 
    gameid INTEGER primary key, 
    starttime datetime DEFAULT NOW() 
); 
CREATE INDEX test_starttime_idx ON test(starttime DESC); 
explain SELECT distinct gameid,starttime FROM  test ORDER BY starttime DESC limit 10;