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

hvor rownum=1 forespørgsel tager tid i Oracle

Dette spørgsmål er allerede blevet besvaret, jeg vil blot give en forklaring på, hvorfor et filter ROWNUM=1 eller ROWNUM <=1 nogle gange kan resultere i en lang svartid.

Når du støder på et ROWNUM-filter (på en enkelt tabel), vil optimeringsværktøjet producere en FULD SCANNING med COUNT STOPkey. Det betyder, at Oracle begynder at læse rækker, indtil det støder på de første N rækker (her N=1). En fuld scanning aflæser blokke fra den første udstrækning til højvandsmærket. Oracle har ingen måde at bestemme hvilke blokke der indeholder rækker, og hvilke der ikke på forhånd, alle blokke vil derfor blive læst indtil N rækker er fundet. Hvis de første blokke er tomme, kan det resultere i mange læsninger.

Overvej følgende:

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

Som du kan se er antallet af konsistente gets ekstremt højt (for en enkelt række). Denne situation kan opstå i nogle tilfælde, hvor du f.eks. indsætter rækker med /*+APPEND*/ tip (altså over højvandsmærket), og du sletter også de ældste rækker med jævne mellemrum, hvilket resulterer i en masse tom plads i begyndelsen af ​​segmentet.



  1. MySql i DNX 5.0

  2. Hold MySQL-skemaet synkroniseret mellem computere

  3. Parametriserede forespørgsler

  4. Hvordan nulstiller jeg postgresql 9.2 standardbruger (normalt 'postgres') adgangskode på mac os x 10.8.2?