catch-img

Oracle SQLチューニング(第41回)「ROWNUMの理解と関連SQL性能問題の理解」(1/6回)

 今回から6回シリーズで、「ROWNUMの理解と関連SQL性能問題の理解」と題して、情報をお届けします。それでは、早速始めましょう。

 ROWNUMはOracleで提供する仮想カラムで、Select節で使う場合には抽出するデータの順番を付与する用途で使われ、Where節に使う場合には抽出するデータのうち一部データだけ持ってくる用途で使われます。 特にWhere節に使われるROWNUMはインデックスの特性を利用して、部分範囲処理に誘導でき、うまく使えば効率的なSQLになります。

 ROWNUMが1回の順番を付与することと、SQLを解釈するときにROWNUMの使用位置とSQLのコンポーネントとの関係を理解すれば、ROWNUMをより効率的に使用することができるでしょう。

 これから、基本的なROWNUMに対する内容を調べていきましょう。

12.1 ROWNUMデータを先に抽出した後、問い合わせよう

 ROWNUM_T1テーブルには下記のように合計10件のデータがあります。

C1    C2         C3
----- --  ---------
    1 C        101
    2 D        102
    3 E        103
    4 F        104
    5 G        105
    6 H        106
    7 I        107
    8 J        108
    9 K        109
   10 L        110

10件のデータに対して下記のようにSQLを実行してみましょう。

テーブル12-1. ROWNUMのデータ抽出

SQL[1]


SQL[2]


SELECT * 
  FROM (SELECT * 
           FROM t1 
        ORDER BY c1)
 WHERE ROWNUM >= 1 
   AND ROWNUM <= 5;

C1   C2   C3
—   — —-
  1   C   101
  2   D   102
3   E   103
4   F   104
  5   G   105

SELECT * 
  FROM (SELECT * 
           FROM t1 
       ORDER BY c1)
 WHERE ROWNUM >= 6 
 AND ROWNUM <= 10;

no rows selected

 SQL[1]とSQL[2]はそれぞれの条件に合うデータが抽出されなければならないと予想されました。 しかしSQL[1]は1 ~ 5まで合計5件のデータが抽出されましたが、SQL[2]は何のデータも抽出されませんでした。

 このような結果が導き出された理由は何なのでしょうか?

 解答はROWNUMの特性で探してみることで得ることができます。 ROWNUMはSQL結果セットに順番を付与する仮想カラムで、Fetch段階で抽出する最初の行に1を付与します。 そして次の行が抽出されるたびにROWNUMの値を次々と増加させます。 ところで1が存在しないならば、次の順番を付与できないので何のデータも抽出されません。

 すなわち、ROWNUMを利用して、ただ一件(ROWNUM=1)のデータだけ抽出したり、1から始めて順にN件のデータを抽出するのは可能ですが、ROWNUMの開始を1でない値から抽出しようとする場合にはデータが抽出されません。

ROWNUMの使用を誤った事例

  WHERE ROWNUM = N ( N > 1 )
  WHERE ROWNUM > N ( N > 1 )

 それならSQL[2]が本来の作成意図のとおりデータを抽出できる方法はないのでしょうか?

 ROWNUMが6 ~ 10のデータ(C1値が6 ~ 10)を抽出するためには、次のSQLのように先に抽出対象データにROWNUMを1から順番を付けた後ROWNUMが6 ~ 10までのデータを抽出すれば良いのです。

SELECT c1, c2, c3, RNUM
  FROM (
        SELECT ROWNUM rnum,
                 t1.*
          FROM (SELECT * FROM t1 ORDER BY c1) T1
)
WHERE rnum >= 6 and rnum <= 10 ;

   C1 C2         C3
----- -- ----------
    6 H        106
    7 I        107
    8 J        108
    9 K        109
   10 L        110




いかがでしたでしょうか?次回は、「ORDER BYとROWNUMを同じ位置に置くのをやめよう」という内容でお送りします。ご期待ください。では、See You ^^


CONTACT

他社に頼らず自社でデータベースを監視・運用をしませんか?
MaxGaugeがサポートします

お役立ち資料は
こちらから

不明点がある方は、
こちらからお問い合わせください

お電話でのお問い合わせはこちら

平日 10時~18時

人気記事ランキング

タグ一覧