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

dove rownum=1 query che richiede tempo in Oracle

Questa domanda ha già avuto risposta, fornirò solo una spiegazione del motivo per cui a volte un filtro ROWNUM=1 o ROWNUM <=1 può comportare un tempo di risposta lungo.

Quando incontra un filtro ROWNUM (su una singola tabella), l'ottimizzatore produrrà una SCANSIONE COMPLETA con COUNT STOPKEY. Ciò significa che Oracle inizierà a leggere le righe finché non incontra le prime N righe (qui N=1). Una scansione completa legge i blocchi dalla prima estensione fino all'high water mark. Oracle non ha modo di determinare quali blocchi contengono righe e quali no in anticipo, tutti i blocchi verranno quindi letti fino a quando non vengono trovate N righe. Se i primi blocchi sono vuoti, potrebbero verificarsi molte letture.

Considera quanto segue:

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

Come puoi vedere, il numero di get coerenti è estremamente alto (per una singola riga). Questa situazione potrebbe verificarsi in alcuni casi in cui, ad esempio, si inseriscono righe con /*+APPEND*/ suggerimento (quindi sopra il limite massimo) ed elimini periodicamente anche le righe più vecchie, risultando in molto spazio vuoto all'inizio del segmento.