Oracle
 sql >> Baza danych >  >> RDS >> Oracle

gdzie rownum=1 zapytanie zajmuje czas w Oracle

Na to pytanie już udzielono odpowiedzi, podam tylko wyjaśnienie, dlaczego czasami filtr ROWNUM=1 lub ROWNUM <=1 może skutkować długim czasem odpowiedzi.

W przypadku napotkania filtra ROWNUM (w pojedynczej tabeli) optymalizator wygeneruje PEŁNE SKANOWANIE z COUNT STOPKEY. Oznacza to, że Oracle rozpocznie odczytywanie wierszy, dopóki nie napotka pierwszych N wierszy (tutaj N=1). Pełny skan odczytuje bloki od pierwszego stopnia do znaku wysokiego poziomu. Oracle nie ma możliwości określenia, które bloki zawierają wiersze, a które nie, dlatego wszystkie bloki będą odczytywane, dopóki nie zostanie znalezionych N wierszy. Jeśli pierwsze bloki są puste, może to spowodować wiele odczytów.

Rozważ następujące kwestie:

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

Jak widać, liczba spójnych pobrań jest niezwykle wysoka (dla jednego rzędu). Taka sytuacja może wystąpić w niektórych przypadkach, gdy na przykład wstawiasz wiersze z /*+APPEND*/ wskazówka (czyli powyżej znaku wodnego), a także okresowo usuwasz najstarsze wiersze, co skutkuje dużą ilością pustego miejsca na początku segmentu.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Podzapytanie Oracle w słowie kluczowym jest wolne na 12c

  2. Jak określić rozmiar tabel w Oracle?

  3. Utrzymywanie agnostyki bazy danych aplikacji (ADO.NET vs enkapsulacja logiki DB)

  4. Tworzenie wyzwalacza, który będzie uruchamiany tylko wtedy, gdy tworzona jest nowa tabela

  5. Łączenie ciągów zagregowanych w Oracle 10g