Oracle
 sql >> база данни >  >> RDS >> Oracle

Какво не е наред с Cursors?

Това, което не е наред с курсорите, е, че често се злоупотребява с тях, както в Oracle и в MS SQL .

Курсорът служи за поддържане на стабилен набор от резултати, който можете да извличате ред по ред. Те се създават имплицитно, когато вашата заявка се изпълнява, и се затварят, когато тя приключи.

Разбира се, поддържането на такъв набор от резултати изисква някои ресурси:locks , latches , memory , дори disk space .

Колкото по-бързо се освободят тези ресурси, толкова по-добре.

Да държите курсор отворен е като да държите вратата на хладилника отворена

Не го правите с часове без необходимост, но това не означава, че никога не трябва да отваряте хладилника си.

Това означава, че:

  • Не получавате резултатите си ред по ред и не ги сумирате:извиквате SQL SUM на вместо това.
  • Не изпълнявате цялата заявка и не получавате първите резултати от курсора:добавяте rownum <= 10 условие за вашата заявка

и т.н.

Що се отнася до Oracle , обработката на вашите курсори вътре в процедура изисква прословутото SQL/PLSQL context switch което се случва всеки път, когато получите резултат от SQL заявка извън курсора.

Това включва предаване на големи количества данни между нишки и синхронизиране на нишките.

Това е едно от най-дразнещите неща в Oracle .

Една от по-малко очевидните последици от това поведение е, че тригерите в 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 секунди с празен тригер, който не прави нищо.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Вмъкване на Oracle при връщане

  2. Извикване на недефинирана функция oci_connect()

  3. Как да експортирате резултатите от заявката в CSV файл в SQL Developer (Oracle)

  4. Можете ли да ми помогнете да напиша процедура в Oracle за изпращане на данни от таблица в CSV файл?

  5. оратоп