SELECT *
FROM (
SELECT *
FROM mytable
WHERE lastname = 'Jones'
ORDER BY
id
)
WHERE rownum <= 200
また
SELECT *
FROM (
SELECT *, ROW_NUMBER() OVER (ORDER BY id) rn
FROM mytable
WHERE lastname = 'Jones'
)
WHERE rn <= 200
後者はでは遅くなりまし9i
たが、でまったく同じように機能し10g+
ます。
私の理解では、rownumは、クエリが実行された後、結果セット全体に適用されます。
いいえ。条項rownum
を満たす各レコードがフェッチされるとすぐに(ただし、順序付けされる前に)適用されます。WHERE
ROWNUM
実際には、がの前に評価されるため、ここではネストされたクエリが必要ですORDER BY
。
ROWNUM
との両方ROW_NUMBER()
が最適化の対象となります。にインデックスがある場合(lastname, id)
、クエリはインデックスを使用し、200番目のレコードを返した後に停止します(COUNT(STOPKEY)
プランにが表示されます)。
ROWNUM
また、ページングに関する一般的な警告があります。このクエリ:
SELECT *
FROM (
SELECT *
FROM mytable
WHERE lastname = 'Jones'
ORDER BY
id
)
WHERE rownum BETWEEN 201 AND 400
ROWNUM
それ自体が条件の一部であるため、何も返されませんWHERE
。エンジンは最初の行を返すことができません。これは、句ROWNUM = 1
を満たさない行があるためです。WHERE
これを回避するには、クエリをダブルネストする必要があります。
SELECT *
FROM (
SELECT q.*, ROWNUM AS rn
FROM (
SELECT *
FROM mytable
WHERE lastname = 'Jones'
ORDER BY
id
) q
)
WHERE rn BETWEEN 201 AND 400
これも最適化されCOUNT(STOPKEY)
ます。