displaytag を使用して、データベースのデータを使用してテーブルを作成しています。これは、要求されたリストがそれほど大きくない場合はうまく機能しますが、リストのサイズが 2500 エントリを超えると、結果リストの取得に非常に時間がかかります (5 分以上)。この行動が正常なのか疑問に思いました。
大きな結果を返す大きなリスト/クエリをどのように処理しますか?
displaytag を使用して、データベースのデータを使用してテーブルを作成しています。これは、要求されたリストがそれほど大きくない場合はうまく機能しますが、リストのサイズが 2500 エントリを超えると、結果リストの取得に非常に時間がかかります (5 分以上)。この行動が正常なのか疑問に思いました。
大きな結果を返す大きなリスト/クエリをどのように処理しますか?
この記事は、問題を解決する方法のサンプル アプリにリンクしています。Displaytag は、ページング リンクを作成し、並べ替えを処理するために、完全なデータセットが渡されることを想定しています。この種のデータは、外部からデータをページングし、要求された行のみをフェッチするという考えを破ります (ユーザーがそれらにページングするため)。記事にリンクされているプロジェクトでは、この種のものを設定する方法について説明しています。
大規模なデータベースを使用している場合、クエリの実行で問題が発生する可能性もあります。私はあなたがこれを除外したと仮定します。そうでない場合は、前述の SQL があります。DB2 クエリ アナライザーで SQL を実行して、DB のボトルネックがないかどうかを確認します。チェーンの次のステップは、単体テストで Hibernate/DAO 呼び出しのテストを実行することです。繰り返しますが、あなたの言葉遣いから、あなたはすでにこれを行っているように思えます。
Displaytagは、すべてをメモリ(セッション)に転送して保存します。Hibernateもそれを行います。DBテーブルの内容全体を一度にメモリに保存する必要はありません(ただし、スローダウンがすでに2500行で始まっている場合は、SQLクエリ/DBテーブルの最適化が不十分な問題のように見えます。2500行はピーナッツになります。まともなDBですが、それは別の話です)。
むしろ、JSTL c:forEach
とELのショットをほとんど使わずに、自分でHTMLテーブルを作成してください。1つまたは2つのリクエストパラメータをバックグラウンドで保持しますinput type="hidden"
:最初に表示される行(firstrow
)、最終的には一度に表示される行数(rowcount
)。
次に、DAOクラスでSELECT stuff FROM data LIMIT firstrow OFFSET rowcount
、使用するDBに応じて、またはそのようなことを実行します。LIMIT
MySQLとPostgreSQLでは、そのようなand/orOFFSET
句を使用できます。Oracleでは、サブクエリを実行する必要があります。MSSQLおよびDB2では、SPを作成する必要があります。あなたはHQLでそれを行うことができます。
次に、テーブルをページングするには、サーバー側のコードに毎回firstrow
withをインクリメント/デクリメントするように指示する一連のボタンを用意します。rowcount
ただ数学をしてください。
編集:DB2を使用しているとコメントしました。少し調べてみましたが、UDBOLAP関数ROW_NUMBER()
を使用できるようです。
SELECT id, colA, colB, colC
FROM (
SELECT
ROW_NUMBER() OVER (ORDER BY id) AS row, id, colA, colB, colC
FROM
data
) AS temp_data
WHERE
row BETWEEN 1 AND 10;
この例では、テーブルの最初の10行を返す必要がありdata
ます。このクエリをパラメータ化して、すべてのページで再利用できるようにすることができます。これは、Javaのメモリ内のテーブル全体をクエリするよりも効率的です。また、テーブルに適切なインデックスが付けられていることを確認してください。