数百万行 (おそらく 1 か月あたり最大 300 万行) を格納できる iSeries データベース テーブルに最適な SQL クエリを作成しようとしています。各行について私が持っている唯一のキーは、その RRN (行の物理レコード番号である相対レコード番号) です。
私の目標は、テーブルを別の小さなテーブルと結合して、数値列の 1 つをテキストで説明することです。ただし、関連する行数は 200 万を超える場合があり、通常、メモリ不足の状態が原因でクエリが失敗します。そのため、クエリを書き直して、大きなサブセットを他のテーブルと結合しないようにします。そのため、特定の月に 1 ページ (最大 30 行) を選択し、そのサブセットを 2 番目のテーブルに結合するという考え方です。
しかし、私は奇妙な問題に遭遇しました。次のクエリを使用して、ページに必要な行の RRN を取得します。
select t.RRN2 -- Gives correct RRNs
from (
select row_number() over() as SEQ,
rrn(e2) as RRN2, e2.*
from TABLE1 as e2
where e2.UPDATED between '2013-05-01' and '2013-05-31'
order by e2.UPDATED, e2.ACCOUNT
) as t
where t.SEQ > 270 and t.SEQ <= 300 -- Paging
order by t.UPDATED, t.ACCOUNT
このクエリは問題なく機能し、必要な行の正しい RRN を返します。しかし、サブクエリの結果を別のテーブルと結合しようとすると、RRN が変更されました。そのため、結合なしで、クエリを単純な外部クエリ内のサブクエリに単純化しました。
select rrn(e) as RRN, e.*
from TABLE1 as e
where rrn(e) in (
select t.RRN2 -- Gives correct RRNs
from (
select row_number() over() as SEQ,
rrn(e2) as RRN2, e2.*
from TABLE1 as e2
where e2.UPDATED between '2013-05-01' and '2013-05-31'
order by e2.UPDATED, e2.ACCOUNT
) as t
where t.SEQ > 270 and t.SEQ <= 300 -- Paging
order by t.UPDATED, t.ACCOUNT
)
order by e.UPDATED, e.ACCOUNT
外側のクエリは、RRN を行キーとして使用して、サブクエリによって選択された各行のすべての列を単純に取得します。しかし、このクエリは機能しません。まったく異なる RRN を持つ行が返されます。
後続のクエリでテーブルからより詳細な情報を取得するために使用されるため、実際の RRN が必要です。
RRN が異なる結果になる理由について何か考えはありますか?
解像度
クエリを 2 つの呼び出しに分割することにしました。1 つは単純なサブクエリを発行して RRN (行 ID) のみを返す呼び出しで、もう 1 つは残りの JOIN などを実行して各行の完全な情報を取得する呼び出しです。(テーブルは 1 日に 1 回だけ更新され、行が削除されることはないため、タイミングの問題を心配する必要はありません。)
このアプローチは非常にうまく機能しているようです。
補遺
メモリ不足エラーが発生する理由については、これは一部のテスト サーバーのみの制限のようです。約 2m 行までしか処理できないものもあれば、それ以上を処理できるものもあります。したがって、これは管理者がサーバーごとに課したある種の制限であると推測しています。