1

テストケース:

drop table master;
create table master(id int primary key, fk1 int, fk2 int, fk3 int, dataS  varchar(255),    data1 int, data2 int, data3 int, data4 int,data5  int,data6 int,data7 int,data8 int,data9 int,b1 boolean,b2 boolean,b3 boolean,b4 boolean,b5 boolean,b6 boolean,b7 boolean,b8 boolean,b9 boolean,b10 boolean,b11 boolean,b12 boolean,b13 boolean,b14 boolean,b15 boolean,b16 boolean,b17 boolean,b18 boolean,b19 boolean,b20 boolean,b21 boolean,b22 boolean,b23 boolean,b24 boolean,b25 boolean,b26 boolean,b27 boolean,b28 boolean,b29 boolean,b30 boolean,b31 boolean,b32 boolean,b33 boolean,b34 boolean,b35 boolean,b36 boolean,b37 boolean,b38 boolean,b39 boolean,b40 boolean,b41 boolean,b42 boolean,b43 boolean,b44 boolean,b45 boolean,b46 boolean,b47 boolean,b48 boolean,b49 boolean,b50 boolean);

create index idx_comp on master(fk1,fk2,fk3);
@loop 5000000 insert into master values(?, mod(?,100), mod(?,5), ?,'Hello World Hello World Hello World',?, ?, ?,?, ?, ?, ?, ?, ?,true,true,true,true,true,true,false,false,false,true,true,true,true,true,true,true,false,false,false,true,true,true,true,true,true,true,false,false,false,true,true,true,true,true,true,true,false,false,false,true,true,true,true,true,true,true,false,false,false,true);

1.次の select ステートメントには最大 30 秒かかります。応答時間を最適化する方法はありますか?

SELECT count(*), SUM(CONVERT(b1,INT)) ,SUM(CONVERT(b2,INT)),SUM(CONVERT(b3,INT)),SUM(CONVERT(b4,INT)),SUM(CONVERT(b5,INT)),SUM(CONVERT(b6,INT)),SUM(CONVERT(b7,INT)),SUM(CONVERT(b8,INT)),SUM(CONVERT(b9,INT)),SUM(CONVERT(b10,INT)),SUM(CONVERT(b11,INT)),SUM(CONVERT(b12,INT)),SUM(CONVERT(b13,INT)),SUM(CONVERT(b14,INT)),SUM(CONVERT(b15,INT)),SUM(CONVERT(b16,INT))
FROM  master
WHERE fk1=53 AND fk2=3

2.シャットダウン・デフラグをしてみました。しかし、このステートメントは、私のテスト ケースでは約 40 分かかりました。シャットダウンのデフラグ後、選択には最大 15 秒かかります。ステートメントを再度実行すると、1秒未満かかります。サーバーを停止して起動しても、ステートメントは約 1 秒かかります。H2 には永続的なキャッシュがありますか?

インフラストラクチャ: WebBrowser <-> H2 コンソール サーバー <-> H2 DB: h2 1.3.158

4

2 に答える 2

2

プロファイラーの出力によると、主な問題 (93%) はディスクからの読み取りです。H2コンソールでこれを実行しました:

@prof_start;
SELECT ... FROM  master WHERE fk1=53 AND fk2=3;
@prof_stop;

そして得た:

Profiler: top 3 stack trace(s) of 48039 ms [build-158]:
4084/4376 (93%):
at java.io.RandomAccessFile.readBytes(Native Method)
at java.io.RandomAccessFile.read(RandomAccessFile.java:338)
at java.io.RandomAccessFile.readFully(RandomAccessFile.java:397)
at org.h2.store.FileStore.readFully(FileStore.java:285)
at org.h2.store.PageStore.readPage(PageStore.java:1253)
at org.h2.store.PageStore.getPage(PageStore.java:707)
at org.h2.index.PageDataIndex.getPage(PageDataIndex.java:225)
at org.h2.index.PageDataNode.getRowWithKey(PageDataNode.java:269)
at org.h2.index.PageDataNode.getRowWithKey(PageDataNode.java:270)

このEXPLAIN ANALYZE SELECTクエリでは、ディスクから 55,000 ページ (各ページ 2 KB、110 MB) を読み取っています。このようなクエリに対して他のデータベースがどのように機能するかはわかりません。しかし、可能であれば、クエリを変更して、読み取るデータを減らす必要があると思います。

于 2011-08-02T19:16:38.537 に答える
1

データ型変換が既に行われている一時的なテーブル/ビューを持つことは可能ですか? メイン テーブルから時折 (1 晩に 1 回程度) 更新することが可能である場合は、既に行われている変換に使用される多くの処理能力があります。

それが不可能な場合は、「b」列ごとに 1 つずつ、複数のサブ選択を実行することをお勧めします。ここでは、b# = 1 の場所のみをプルします。次に、SUM の代わりに COUNT を実行します。これも高速です。例えば:

SELECT (count1+count2) AS Count, 
(SELECT COUNT(*) FROM master WHERE fk1=53 AND fk2=3 AND b1=1) AS count1
(SELECT COUNT(*) FROM master  WHERE fk1=53 AND fk2=3 AND b2=1) AS count2

その正確な構文があなたのプログラムで機能するかどうかはわかりませんが、うまくいけば、一般的な SQL のアイデアとして、正しい軌道に乗ることができます。

于 2011-08-02T12:40:55.163 に答える