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

OracleデータベースのLIMIT句を使用したPL/SQL一括収集

    OracleデータベースのLIMIT句を使用した一括収集

    これまで、暗黙カーソルと明示カーソルのFETCH-INTOステートメントを使用するSELECT-INTOで一括収集を使用してクエリのパフォーマンスを向上させる方法を学びました。しかし、クエリをさらに最適化する余地はまだあるのでしょうか。このブログでは、一括収集でLimit句を使用してクエリをさらに改善する方法を学習します。

    select-intoで一括収集を使用して複数のスイッチを圧縮するプロセスをすでに学習しました。次に、明示カーソルのfetch-intoステートメントで同じものを使用することで、クエリをより細かく制御できます。しかし、私たちの注意が必要な問題がまだあります。それは、一括収集によって引き起こされる過度のメモリの枯渇です。

    一括収集によって引き起こされる過度のメモリ枯渇とはどういう意味ですか?

    一括収集句を使用して多数のレコードを取得またはフェッチするたびに、プログラムは高速かつ効率的にするために大量のメモリを消費し始めます。これは単なる記憶ではありません。 Oracle Databaseのすべてのセッション間で共有されるSGAメモリとは異なり、プログラムは各セッションに特別に割り当てられたPGAメモリを消費します。

    これにより、データベースのパフォーマンスが低下します。これは、クエリが確実にうまく機能している必要があることを意味しますが、同時に、データベースはそうではない可能性があります。

    データベース全体のパフォーマンスを低下させることによって、十分に最適化されたクエリを作成することはできません。でしょ?

    一括収集によるメモリ枯渇のこの問題をどのように解決できますか?

    一括収集を使用してフェッチされるデータの量を制御および制約できれば、このメモリ枯渇の問題は簡単に克服できます。これは、LIMIT句を指定したBulkCollectを使用して行うことができます。

    LIMIT句の構文は何ですか?

    LIMIT句はFETCH-INTOステートメントの属性として機能します:

    FETCH <cursor_name> BULK COLLECT INTO <plsql_collection> LIMIT number;

    LIMITはFETCH-INTOステートメントの属性として機能するため、これを使用するには、キーワードLIMITの後に特定の数字を追加して、バルク収集句がFETCHの最後に一度に取得する行数を指定できます。 -INTOステートメント。

    LIMIT句は何をしますか?

    LIMIT句は、BULKCOLLECTとFETCHステートメントを使用してフェッチされる行数を制限します。

    SELECT-INTOステートメントでLIMIT句を使用できますか?

    いいえ、SELECT-INTOステートメントでLIMIT句を使用することはできません。 LIMIT句はFETCH-INTOステートメントの属性として機能します。これは、LIMIT句が機能するには明示的なカーソルが必要であり、FETCH-INTOステートメントは明示的なカーソルライフサイクルの一部であるためです。

    したがって、LIMIT句は、FETCH-INTOステートメントでBULKCOLLECTを使用している場合にのみ使用できることを常に覚えておいてください。 SELECT-INTOステートメントで一括収集を使用している場合は使用できません。

    例:Oracleデータベースの一括収集ステートメントでLIMIT句を使用する方法

    これは、LIMIT句を操作する方法を示す非常に簡単な例です。

    SET SERVEROUTPUT ON;
    DECLARE
        CURSOR exp_cur IS
        SELECT first_name FROM employees;
        
        TYPE nt_fName   IS TABLE OF VARCHAR2(20);
        fname   nt_fName;
    BEGIN
        OPEN exp_cur;
        FETCH exp_cur   BULK COLLECT INTO fname     LIMIT 10;
        CLOSE exp_cur;
        --Print data
        FOR idx IN 1 .. fname.COUNT
        LOOP
            DBMS_OUTPUT.PUT_LINE (idx||' '||fname(idx) );
        END LOOP;
    END;
    /
    

    上記のコードの詳細な説明については、私のYouTubeチャンネルのビデオチュートリアルを参照してください。

    したがって、今回は、すべてのレコードをフェッチしてメモリなどの高価なリソースを使い果たす代わりに、LIMIT句のおかげで、必要な行のみを取得し、リソースを無駄にすることもありません。このようにして、一括収集を使用してクエリのパフォーマンスを1段階上げることができます。

    では、マニッシュ、取得できる行の適切な量を尋ねます。

    この質問に対する答えを知るために、オラクルのWebサイトで私の親友であるStevenFeuersteinによるこのブログを読むことをお勧めします。彼はこの質問に本当によく答えました。

    このアプローチにも欠点があります。つまり、この同じプログラムを再度実行すると、LIMIT句を指定したこのFETCH-INTOステートメントは、コレクションに次の10レコードを追加しません。むしろ、テーブルを切り捨てて、インデックス番号1からネストされたテーブルに再度データを入力します。

    親愛なる友人のコナー・マクドナルドが、MULTISETを使用してこの問題を克服する方法を説明するブログを作成しました。さあ、彼の記事をチェックしてください。

    これは、OracleDatabaseの一括収集でLIMIT句を使用する方法に関する詳細なPL/SQLブログです。あなたが読書を楽しんだことを願っています、もしそうなら、あなたのソーシャルメディアであなたの友人とこのチュートリアルを共有することを忘れないでください。読んでくれてありがとう。良い一日を!


    1. MySQLでのRIGHT()関数のしくみ

    2. 行から最大値を取得して別のテーブルに結合する

    3. SQL:フルネームフィールドから名、ミドルネーム、ラストネームを解析します

    4. 条件付きSQLカウント