sql >> データベース >  >> RDS >> Oracle

ROWNUM =1は、どのような条件下で、既存のスタイルクエリのパフォーマンスを大幅に向上させますか

    単純な単一インデックスルックアップでは解決できないクエリのパフォーマンスが大幅に向上します(平均で数十パーセント)。テーブルが結合します。ただし、データ/アプリケーションエラーを非表示にする可能性があります。

    テーブルを作成しましょう:

    create table t (id number(10,0), padding varchar2(1000));  
    

    -例をできるだけ単純にするために、意図的にPKを使用しないでください。パディングは、各レコードの実際のデータ負荷をシミュレートするために使用されます

    多くの記録がある:

    insert into t (id, padding)
    select rownum, rpad(' ', 1000) from dual connect by level < 10000
    

    さて、あなたが次のようなことを尋ねたら

    select 1 into ll_exists
    from t where id = 5;
    

    DBは、最初のデータブロック(さまざまな方法で挿入される可能性があるためわかりません)で一致するレコードのみが見つかったか、最後のデータブロックで見つかったかにかかわらず、テーブル全体を調べる必要があります。これは、一致するレコードが1つしかないことを認識していないためです。一方、...を使用し、rownum =1の場合、別の一致するレコードがない(または不要である)と言ったため、レコードが見つかった後、データのトラバースを停止できます。

    欠点は、rownum制約を使用すると、データに複数の可能なレコードが含まれている場合に不確定な結果が得られる可能性があることです。クエリが

    select id into ll_id
    from t where mod (id, 2) = 1
    and rownum = 1;
    

    それから私はDBから答え1と3と123を受け取るかもしれません...順序は保証されていません、そしてこれは結果です。 (rownum句がないと、TOO_MANY_ROWS例外が発生します。どちらが悪いかは状況によって異なります)

    存在をテストするクエリが本当に必要な場合は、そのように記述してください。

    begin
    
    select 'It does' 
      into ls_exists
    from dual where
    exists (your_original_query_without_rownum);
    
    do_something_when_it_does_exist
    exception
      when no_data_found then
        do_something_when_it_doesn't_exist
    end;
    


    1. sqlalchemyとpyodbcを使用してSQLServer2012に接続する

    2. byteaとして取得されたPostgreSQLJDBCNull文字列

    3. 空の列を検出して削除し、SQL、Oracleのデータベースを更新します

    4. MySQLで月と年でグループ化