カーソルの何が問題になっているのかというと、Oracle
の両方でカーソルが悪用されることがよくあるということです。 およびMS SQL
。
カーソルは、行ごとに取得できる安定した結果セットを維持するためのものです。これらは、クエリの実行時に暗黙的に作成され、クエリが終了すると閉じられます。
もちろん、そのような結果セットを維持するには、いくつかのリソースが必要です:locks
、latches
、memory
、disk space
。
これらのリソースが解放されるのが早いほど、優れています。
カーソルを開いたままにしておくことは、冷蔵庫のドアを開いたままにしておくようなものです
必要のない時間は何時間もしませんが、冷蔵庫を絶対に開けてはいけないという意味ではありません。
つまり:
- 結果を行ごとに取得して合計することはできません。
SQL
を呼び出します。 のSUM
代わりに。 - クエリ全体を実行してカーソルから最初の結果を取得するのではなく、
rownum <= 10
を追加します。 クエリの条件
、など。
Oracle
について 、プロシージャ内でカーソルを処理するには、悪名高いSQL/PLSQL context switch
が必要です。 これは、SQL
の結果を取得するたびに発生します カーソルからクエリを実行します。
スレッド間で大量のデータを渡し、スレッドを同期する必要があります。
これは、Oracle
で最も苛立たしいことの1つです。 。
その振る舞いのあまり明白でない結果の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
空のトリガーが何もしない秒。