sql >> Database teknologi >  >> RDS >> Oracle

Hvad er der galt med Cursors?

Hvad der er galt med markører er, at de ofte bliver misbrugt, både i Oracle og i MS SQL .

Markørerne er til at holde et stabilt resultatsæt, som du kan hente række-for-række. De oprettes implicit, når din forespørgsel køres, og lukkes, når den er færdig.

Selvfølgelig kræver det nogle ressourcer at holde et sådant resultatsæt:locks , locks , memory , endda disk space .

Jo hurtigere disse ressourcer frigives, jo bedre.

At holde en markør åben er som at holde en køleskabsdør åben

Du gør det ikke i timevis uden at det er nødvendigt, men det betyder ikke, at du aldrig skal åbne dit køleskab.

Det betyder, at:

  • Du får ikke dine resultater række for række og summere dem:du kalder SQL s SUM i stedet.
  • Du udfører ikke hele forespørgslen og får de første resultater fra markøren:du tilføjer en rownum <= 10 betingelse for din forespørgsel

osv.

Hvad angår Oracle , at behandle dine markører i en procedure kræver berygtet SQL/PLSQL context switch hvilket sker hver gang du får et resultat af en SQL forespørg ud af markøren.

Det involverer at sende store mængder data mellem tråde og synkronisere trådene.

Dette er en af ​​de mest irriterende ting i Oracle .

En af de mindre indlysende konsekvenser af denne adfærd er, at triggere i Oracle bør undgås, hvis det er muligt.

Oprettelse af en trigger og kalder en DML funktion er lig med at åbne markøren ved at vælge de opdaterede rækker og kalde triggerkoden for hver række af denne markør.

Alene eksistensen af ​​triggeren (selv den tomme trigger) kan bremse en DML operation 10 times eller mere.

Et testscript på 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 sekunder uden en trigger, 17.57 sekunder med en tom trigger, der ikke gør noget.



  1. Ingen dialektkortlægning for JDBC-type:-9

  2. Hvordan får man de generelt mest populære tags fra normaliserede tabeller?

  3. Eksport af en MySQL-tabel til en CSV-fil

  4. Mysqldump:Kan du ændre navnet på den tabel, du indsætter i?