ページングにROWNUMBER関数を使用するSQLのパフォーマンスが低いです。ページサイズは5000に設定されていましたが、100に変更されました。低環境でのテストでは、この変更後の応答時間が7秒から1秒に短縮されました。SQL ROWNUMBER効率
しかし、クエリにはフィルタがあまり多くないため、たとえば、述語のLAST_UPD_DTが今日に設定されていると、完全なテーブルスキャンが行われる可能性があります。
このような状況では、ROWNUMBERをはるかに低い値のヘルプに設定したり、少しの違いを作ったりしますか?
プロダクションには約250万のレコードがあり、テストでは約5kのレスポンスが7秒から1秒に下がったことがわかりました。
クエリは、述語と同じ列を持つインデックスを使用します。現在、ORIG_TIME列には索引はありませんが、追加されます。データベースはDB2です。
以下は、問題の基本的なエッセンスを保持するクエリのトリムダウンバージョンです。
SELECT *
FROM
(
SELECT ROWNUMBER () OVER (
ORDER BY MEMBERS.ORIG_TIME ASC),
MEMBERS.APP_ID,
MEMBERS.NAME
FROM MEMBERS
WHERE
MEMBERS.LAST_UPD_DT <= ? AND
(MEMBERS.STAT_CD = 'S' OR MEMBERS.CURR_STAT = 'D')
ORDER BY MEMBERS.ORIG_TIME ASC
)
AS TEMP_
WHERE ROWNUMBER_ <= 100 --used to be 5000
ご意見やご協力をいただければ幸いです。ありがとうございました。
は 'last_upd_dt'フィールドインデックスされますか?もしそうなら、あなたはなぜテーブルスキャンがあると思いますか? –
@ダンブルクックはいそうです。おそらく私は間違っていますが、クエリが大量のレコードをテーブルから戻した場合、オプティマイザはインデックス検索よりもテーブルスキャンを実行する方が効率的ではないと判断して、テーブルからデータを読み込みます。 subselectの 'ORDER BY MEMBERS.ORIG_TIME ASC'は – scifi2008
です。その注文が必要な場合は、外側の選択の後に置く。 – mustaccio