Oracle
 sql >> Baza danych >  >> RDS >> Oracle

Co jest nie tak z kursorami?

Co jest nie tak z kursorami to to, że są one często nadużywane, zarówno w Oracle oraz w MS SQL .

Kursor służy do utrzymywania stabilnego zestawu wyników, który można pobierać wiersz po wierszu. Są one tworzone niejawnie po uruchomieniu zapytania i zamykane po jego zakończeniu.

Oczywiście utrzymanie takiego zestawu wyników wymaga pewnych zasobów:locks , latches , memory , nawet disk space .

Im szybciej te zasoby zostaną zwolnione, tym lepiej.

Utrzymywanie otwartego kursora jest jak otwieranie drzwi lodówki

Nie robisz tego godzinami bez konieczności, ale to nie znaczy, że nigdy nie powinieneś otwierać lodówki.

Oznacza to, że:

  • Nie otrzymujesz wyników wiersz po wierszu i nie sumujesz ich:wywołujesz SQL SUM zamiast tego.
  • Nie wykonujesz całego zapytania i otrzymujesz pierwsze wyniki z kursora:dołączasz rownum <= 10 warunek zapytania

itp.

Co do Oracle , przetwarzanie kursorów wewnątrz procedury wymaga niesławnego SQL/PLSQL context switch co dzieje się za każdym razem, gdy otrzymujesz wynik SQL zapytanie poza kursorem.

Polega na przesyłaniu dużych ilości danych między wątkami i synchronizowaniu wątków.

To jedna z najbardziej irytujących rzeczy w Oracle .

Jedną z mniej oczywistych konsekwencji takiego zachowania jest to, że w miarę możliwości należy unikać wyzwalaczy w Oracle.

Tworzenie wyzwalacza i wywoływanie DML funkcja jest równa otwarciu kursora, wybraniu zaktualizowanych wierszy i wywołaniu kodu wyzwalającego dla każdego wiersza tego kursora.

Samo istnienie wyzwalacza (nawet pustego wyzwalacza) może spowolnić DML operacja 10 times lub więcej.

Skrypt testowy na 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 sekundy bez wyzwalacza, 17.57 sekundy z pustym spustem, który nic nie robi.



  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 SQL:Filtrowanie według ROWNUM nie zwraca wyników, gdy powinno

  2. Przykłady ciągów i liczb konkatenacji Oracle

  3. Odbierz przywileje w Oracle

  4. Jak wybrać * plus kolejna kolumna

  5. Musisz liczyć rekordy i liczyć grupy według daty w bazie danych Oracle za pomocą programisty sql