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

Oracleの一時データのパフォーマンスに関する考慮事項

    一時テーブルは、キャッシュと非同期I / Oのおかげで、実質的にメモリ内テーブルと同じです。一時テーブルソリューションでは、SQLとPL/SQL間の変換にオーバーヘッドは必要ありません。

    結果の確認

    2つのバージョンをRunStatsと比較すると、一時テーブルバージョンは見た目 ずっと悪いです。 Run1の一時テーブルバージョンのすべてのジャンクと、Run2のPL/SQLバージョンのわずかな追加メモリ。最初は、PL/SQLが明らかに勝者になるはずです。

    Type  Name                              Run1 (temp) Run2 (PLSQL)         Diff
    ----- -------------------------------- ------------ ------------ ------------
    ...
    STAT  physical read bytes                    81,920            0      -81,920
    STAT  physical read total bytes              81,920            0      -81,920
    LATCH cache buffers chains                  104,663          462     -104,201
    STAT  session uga memory                    445,488      681,016      235,528
    STAT  KTFB alloc space (block)            2,097,152            0   -2,097,152
    STAT  undo change vector size             2,350,188            0   -2,350,188
    STAT  redo size                           2,804,516            0   -2,804,516
    STAT  temp space allocated (bytes)       12,582,912            0  -12,582,912
    STAT  table scan rows gotten             15,499,845            0  -15,499,845
    STAT  session pga memory                    196,608   19,857,408   19,660,800
    STAT  logical read bytes from cache     299,958,272            0 -299,958,272
    

    しかし、結局のところ、重要なのは壁掛け時計の時間だけです。一時テーブルを使用すると、読み込みとクエリの両方の手順がはるかに高速に実行されます。

    PL / SQLバージョンは、BULK COLLECTを置き換えることで改善できます。 with cast(collect(test_o(MOD(a, 10), '' || MOD(a, 12))) as test_t) INTO t 。ただし、それでも一時テーブルバージョンよりも大幅に低速です。

    最適化された読み取り

    小さな一時テーブルからの読み取りでは、メモリ内にあるバッファキャッシュのみが使用されます。クエリ部分のみを何度も実行し、consistent gets from cache (メモリ)physical reads cache中に増加します (ディスク)同じままです。

    select name, value
    from v$sysstat
    where name in ('db block gets from cache', 'consistent gets from cache', 
    'physical reads cache');
    

    最適化された書き込み

    特に一時テーブルがON COMMIT DELETE ROWSであるため、物理的なI/Oがないことが理想的です。 。そして、Oracleの次のバージョンがそのようなメカニズムを導入するかもしれないように思えます。ただし、この場合はそれほど重要ではありません。ディスクI/Oによって速度が低下することはないようです。

    ロードステップを複数回実行してから、select * from v$active_session_history order by sample_time desc;を実行します。 。ほとんどのI/OはBACKGROUNDです 、これは何も待っていないことを意味します。一時テーブルの内部ロジックは、通常のDMLメカニズムの単なるコピーであると思います。一般に、新しいテーブルデータは コミットされている場合は、ディスクに書き込む必要があります。オラクルは、たとえばログバッファからディスクにデータを移動することによって作業を開始する場合がありますが、実際のCOMMITが存在するまで急ぐことはありません。 。

    PL / SQLの時間はどこに行きますか?

    私は見当もつかない。複数のコンテキストスイッチがありますか、それともSQLエンジンとPL / SQLエンジンの間に単一の変換がありますか?私の知る限り、利用可能なメトリックのいずれも時間を示していません SQLとPL/SQLの切り替えに費やしました。

    PL/SQLコードが遅い理由を正確に知ることはできないかもしれません。あまり気にしません。一般的な答えは、データベース作業の大部分はとにかくSQLで行わなければならないということです。 Oracleが、アドオン言語であるPL / SQLよりも、データベースのコアであるSQLの最適化に多くの時間を費やした場合は非常に理にかなっています。

    追記

    パフォーマンステストでは、connect byを削除すると便利な場合があります 別のステップへのロジック。このSQLはデータをロードするための優れたトリックですが、非常に遅く、リソースを大量に消費する可能性があります。そのトリックでサンプルテーブルを一度ロードしてから、そのテーブルから挿入する方が現実的です。

    新しいOracle12c機能である一時的な取り消しと新しい18c機能であるプライベート一時テーブルを使用してみました。どちらも通常の一時テーブルよりもパフォーマンスが向上しませんでした。

    私はそれには賭けませんが、データが大きくなるにつれて結果が完全に変化する方法を見ることができます。ログバッファとバッファキャッシュは非常に大きくなるだけです。そして最終的には、そのバックグラウンドI / Oが追加されて一部のプロセスを圧倒し、BACKGROUNDを変える可能性があります。 FOREGROUNDで待ちます 待つ。一方、PL / SQLソリューション用のPGAメモリはそれほど多くないため、問題が発生します。

    最後に、これは「インメモリデータベース」に対する私の懐疑論を部分的に裏付けています。キャッシングは目新しいことではなく、データベースは何十年もの間それを行ってきました。



    1. オプションで列を検索するストアドプロシージャを作成するにはどうすればよいですか?

    2. ScaleGridがマネージドデータベースホスティングのGoogleCloudPlatform(GCP)サポートを開始

    3. ユーザーのJavaJDBCアクセスが拒否されました

    4. MySqlSelectQueryでUTC日​​付をローカルタイムゾーンに変換する方法