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

W jakich warunkach ROWNUM=1 znacząco zwiększa wydajność w istniejącym zapytaniu stylu?

Znacznie poprawia wydajność (średnia w dziesiątkach procent) w przypadku zapytań, których nie można rozwiązać za pomocą prostego wyszukiwania pojedynczego indeksu, np. łączenia tabel. Jednak może potencjalnie ukryć błąd danych/aplikacji.

Zróbmy stolik:

create table t (id number(10,0), padding varchar2(1000));  

--celowo nie używaj PK, aby przykład był tak prosty, jak to tylko możliwe. Wypełnienie służy do symulacji rzeczywistego ładowania danych w każdym rekordzie

z wieloma rekordami:

insert into t (id, padding)
select rownum, rpad(' ', 1000) from dual connect by level < 10000

Teraz, jeśli zapytasz o coś takiego

select 1 into ll_exists
from t where id = 5;

DB musi przejść przez całą tabelę, niezależnie od tego, czy znalazła jedyny pasujący rekord w pierwszym bloku danych (którego, nawiasem mówiąc, nie wiemy, ponieważ można go wstawić na wiele różnych sposobów), czy w ostatnim. To dlatego, że nie wie, że jest tylko jeden pasujący rekord. Z drugiej strony, jeśli użyjesz ... i rownum =1, może przestać przeglądać dane po znalezieniu rekordu, ponieważ powiedziałeś mu, że nie ma (lub nie jest potrzebny) innego pasującego rekordu.

Wadą jest to, że przy ograniczeniu numeru wiersza możesz uzyskać niedeterministyczne wyniki, jeśli dane zawierają więcej niż jeden możliwy rekord.Jeśli zapytanie było

select id into ll_id
from t where mod (id, 2) = 1
and rownum = 1;

wtedy mogę otrzymać od DB odpowiedź 1 i 3 oraz 123 ... zamówienie nie jest gwarantowane i to jest konsekwencja. (bez klauzuli rownum otrzymałbym wyjątek TOO_MANY_ROWS. To zależy od sytuacji, która jest gorsza)

Jeśli naprawdę chcesz zapytać, które testuje istnienie, NAPISZ TO W TEN SPOSÓB.

begin

select 'It does' 
  into ls_exists
from dual where
exists (your_original_query_without_rownum);

do_something_when_it_does_exist
exception
  when no_data_found then
    do_something_when_it_doesn't_exist
end;


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Unikanie częstego wywoływania tego samego widoku w procedurze Oracle

  2. PLSQL - Iinsert w wyzwalaczu powodujący pętlę rekurencyjną

  3. W Oracle SQL:Jak wstawić bieżącą datę + czas do tabeli?

  4. Kod sql do tworzenia lustrzanego obrazu ciągu w Oracle sql

  5. MyBatis RowBounds nie ogranicza wyników zapytań