Oracle
 sql >> Datenbank >  >> RDS >> Oracle

wobei rownum=1 Abfrage in Oracle Zeit in Anspruch nimmt

Diese Frage wurde bereits beantwortet, ich werde nur erklären, warum manchmal ein Filter ROWNUM=1 oder ROWNUM <=1 zu einer langen Antwortzeit führen kann.

Beim Auffinden eines ROWNUM-Filters (in einer einzelnen Tabelle) erzeugt der Optimierer einen FULL SCAN mit COUNT STOPKEY. Das bedeutet, dass Oracle beginnt, Zeilen zu lesen, bis es auf die ersten N Zeilen stößt (hier N=1). Ein vollständiger Scan liest Blöcke vom ersten Extent bis zur oberen Grenze. Oracle hat keine Möglichkeit, vorher zu bestimmen, welche Blöcke Zeilen enthalten und welche nicht, daher werden alle Blöcke gelesen, bis N Zeilen gefunden werden. Wenn die ersten Blöcke leer sind, kann dies zu vielen Lesevorgängen führen.

Beachten Sie Folgendes:

SQL> /* rows will take a lot of space because of the CHAR column */
SQL> create table example (id number, fill char(2000));

Table created

SQL> insert into example 
  2     select rownum, 'x' from all_objects where rownum <= 100000;

100000 rows inserted

SQL> commit;

Commit complete

SQL> delete from example where id <= 99000;

99000 rows deleted

SQL> set timing on
SQL> set autotrace traceonly
SQL> select * from example where rownum = 1;

Elapsed: 00:00:05.01

Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=ALL_ROWS (Cost=7 Card=1 Bytes=2015)    
   1    0   COUNT (STOPKEY)
   2    1     TABLE ACCESS (FULL) OF 'EXAMPLE' (TABLE) (Cost=7 Card=1588 [..])

Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
      33211  consistent gets
      25901  physical reads
          0  redo size
       2237  bytes sent via SQL*Net to client
        278  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

Wie Sie sehen können, ist die Anzahl konsistenter Gets extrem hoch (für eine einzelne Zeile). Diese Situation kann in einigen Fällen auftreten, in denen Sie beispielsweise Zeilen mit /*+APPEND*/ einfügen Hinweis (also über der High Water Mark), und Sie löschen auch regelmäßig die ältesten Zeilen, was zu viel leerem Platz am Anfang des Segments führt.