Strona główna > Oracle Database > Nie ufaj kosztowi zapytania

Nie ufaj kosztowi zapytania

Witajcie. Dawno nie pisałem, głównie z braku weny… Dzisiaj jednak postanowiłem nadrobić zaległości. Padły pewne zarzuty, że blog jest mało konkretny/techniczny, więc dzisiejszy post niech będzie małą wprawką🙂

Prosty przykład. Na razie bez szczegółów.

  • Tabele oraz indeksy mają odpowiednio zebrane statystyki.
  • Tabela A zawiera 14 184 446 wierszy.
  • Tabela B zawiera 2 322 917 wierszy.
  • Obszary SGA i PGA zarządzane są przez (nowy w Oracle 11g) parametr MEMORY_TARGET – ustawiony na 8GB
  • Tabele nie są spartycjonowane
  • W systemie nie działają inne znaczące procesy – jednym słowem cały procesor i cała przepustowość dysku jest do wykorzystania
  • Używana jest macierz dyskowa, o bliżej nieznanych mi parametrach

Zapytanie bazowe:

SELECT A.lista_kolumn, B.lista_kolumn
FROM tabela_a A LEFT OUTER JOIN tabela_b B ON warunek_zlaczenia;

Warunek złączenia jest zwykłym warunkiem równościowym. Tabela A będzie zawsze czytana cała, więc brany będzie FULL SCAN tabeli. Można więc rozbić ten spory koszt poprzez dodanie hinta PARALLEL.

Zapytanie z hintem PARALLEL:

SELECT /*+ PARALLEL(A,5) */ A.lista_kolumn, B.lista_kolumn
FROM tabela_a A LEFT OUTER JOIN tabela_b B ON warunek_zlaczenia;

Mimo, że na tabela_b istnieje odpowiedni indeks, Oracle generuje plan zapytania, w którym go nie uwzględnia:

Jak widać – Oracle chce użyć metody HASH JOIN, i uważa, że ta metoda będzie szybsza. Można jednak wymusić użycie indeksu.

Zapytanie z hintami PARALLEL i USE_NL:

SELECT /*+ PARALLEL(A,5) USE_NL(B)*/ A.lista_kolumn, B.lista_kolumn
FROM tabela_a A LEFT OUTER JOIN tabela_b B ON warunek_zlaczenia;

USE_NL- podpowiada optymalizatorowi, że chcemy skorzystać ze złączenia typu NESTED LOOPS

Plan zapytania:

Mimo, że koszt drugiego zapytania jest dużo wyższy, zapytanie wykonywane jest szybciej. Uśrednione wyniki to ok 0.6 sekundy dla wersji z indeksem (i metodą złączenia NESTED LOOPS) oraz ok 10 sekund dla wersji bez indeksu (metoda złączenia HASH JOIN) i jednocześnie niższym kosztem. Wstępna konkluzja powinna być oczywista – optymalizator kosztowy czasem się myli – niższy koszt wcale nie musi oznaczać niższego czasu wykonania danej instrukcji SQL.

 

Ale to tylko wierzchołek góry lodowej….

  1. 2014/02/07 o 09:57

    mozesz wyjasnic dzialanie hash join?

  1. No trackbacks yet.

Skomentuj

Wprowadź swoje dane lub kliknij jedną z tych ikon, aby się zalogować:

Logo WordPress.com

Komentujesz korzystając z konta WordPress.com. Log Out / Zmień )

Zdjęcie z Twittera

Komentujesz korzystając z konta Twitter. Log Out / Zmień )

Facebook photo

Komentujesz korzystając z konta Facebook. Log Out / Zmień )

Google+ photo

Komentujesz korzystając z konta Google+. Log Out / Zmień )

Connecting to %s

%d bloggers like this: