Oracle
 sql >> база данни >  >> RDS >> Oracle

където rownum=1 заявка отнема време в Oracle

На този въпрос вече е отговорено, просто ще дам обяснение защо понякога филтър ROWNUM=1 или ROWNUM <=1 може да доведе до дълго време за отговор.

Когато срещне филтър ROWNUM (на една таблица), оптимизаторът ще произведе ПЪЛНО СКАНИРАНЕ с COUNT STOPKEY. Това означава, че Oracle ще започне да чете редове, докато не срещне първите N реда (тук N=1). Пълното сканиране чете блокове от първия екстент до знака за висока вода. Oracle няма начин да определи кои блокове съдържат редове и кои не предварително, следователно всички блокове ще бъдат прочетени, докато не бъдат намерени N реда. Ако първите блокове са празни, това може да доведе до много четения.

Имайте предвид следното:

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

Както можете да видите, броят на последователните получавания е изключително голям (за един ред). Тази ситуация може да възникне в някои случаи, когато например вмъквате редове с /*+APPEND*/ подсказка (по този начин над знака за висока вода), а също така периодично изтривате най-старите редове, което води до много празно място в началото на сегмента.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как да създавате PDF отчети с помощта на PL/SQL

  2. Замяна или премахване на няколко реда текст в съхранена процедура на Oracle

  3. Oracle REGEXP_SUBSTR до SUBSTR + INSTR

  4. Oracle sql агрегатна функция със стойности по подразбиране

  5. Синтактична грешка на Oracle