Oracleカーソルの問題点は、との両方で頻繁に乱用されることMS SQLです。
カーソルは、行ごとに取得できる安定した結果セットを保持するためのものです。これらは、クエリの実行時に暗黙的に作成され、終了時に閉じられます。
もちろん、そのような結果セットを保持するには、いくつかのリソースが必要です: locks、latches、memory、さらにはdisk space.
これらのリソースの解放が早ければ早いほど良いです。
カーソルを開いたままにしておくことは、冷蔵庫のドアを開けたままにしておくようなものです
必要なく何時間もそれをするわけではありませんが、決して冷蔵庫を開けてはいけないという意味ではありません。
つまり、次のことを意味します。
- 結果を行ごとに取得して合計するのではなく、代わりに
SQL'sを呼び出しますSUM。
rownum <= 10クエリ全体を実行してカーソルから最初の結果を取得するのではなく、クエリに条件を追加します
など
に関しては、プロシージャ内でカーソルを処理するには、カーソルからクエリの結果を取得するたびに発生Oracleする悪名高いことが必要です。SQL/PLSQL context switchSQL
これには、スレッド間で大量のデータを渡し、スレッドを同期することが含まれます。
これは で最も苛立たしいことの 1 つですOracle。
その動作のあまり明白でない結果の 1 つは、可能であれば Oracle でのトリガーを避ける必要があることです。
トリガーを作成してDML関数を呼び出すことは、カーソルを開いて更新された行を選択し、このカーソルの各行のトリガー コードを呼び出すことと同じです。
DMLトリガーが存在するだけで (空のトリガーであっても)、操作が遅くなる可能性があり10 timesます。
上のテスト スクリプト10g:
SQL> CREATE TABLE trigger_test (id INT NOT NULL)
2 /
Table created
Executed in 0,031 seconds
SQL> INSERT
2 INTO trigger_test
3 SELECT level
4 FROM dual
5 CONNECT BY
6 level <= 1000000
7 /
1000000 rows inserted
Executed in 1,469 seconds
SQL> COMMIT
2 /
Commit complete
Executed in 0 seconds
SQL> TRUNCATE TABLE trigger_test
2 /
Table truncated
Executed in 3 seconds
SQL> CREATE TRIGGER trg_test_ai
2 AFTER INSERT
3 ON trigger_test
4 FOR EACH ROW
5 BEGIN
6 NULL;
7 END;
8 /
Trigger created
Executed in 0,094 seconds
SQL> INSERT
2 INTO trigger_test
3 SELECT level
4 FROM dual
5 CONNECT BY
6 level <= 1000000
7 /
1000000 rows inserted
Executed in 17,578 seconds
1.47トリガーなしの17.57秒、何もしない空のトリガーの秒。