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)ます。