Zapytanie skorelowane - problem

1

Cześć,

Prośba o poradę, spotkaliście się może kiedyś z przypadkiem, kiedy zapytanie z zagnieżdżonym podzapytaniem nie zwraca błędów, jednak nie wykonuje się?

Podam na przykładzie:
Mam zapytanie o konstrukcji dosyć prostej (podaje przykład czysto koncepcyjny):

SELECT
A.parametr1,
B.parametr2,
C.parametr3
FROM tabela1 A, tabela2 B, tabela3 C
WHERE
a.id = b.id and
b.id = c.id and
c.id IN (SELECT D.id FROM tabela4 D
where warunek 1
warunek 2....itd)

Zapytanie wykonuje się w miarę szybko zwracając poprawny wynik na wszystkich bazach danych stałych (nawet tych, o bardzo dużym wolumenie danych, ORACLE 12.x).
W przypadku kiedy wykonuje je jednak na bazie danych, która podlega ciągłej aktualizacji w czasie rzeczywistym (aktualizowane są wszystkie tabele, szczególnie tabela 4)
Zapytanie wykonuje się w nieskończoność... Oracle Developer wisi w stanie (executing query) i w żaden sposób nie mogę zatrzymać tego procesu.

Wykonując dla sprawdzenia zapytanie bez podzapytania, oraz testowo samo podzapytanie otrzymuje normalnie wynik po 2-3 sekundach
Czy fakt, że baza podlega ciągłej aktualizacji i zmieniają się zawartości tabel może mieć tutaj wpływ? (nawet jeśli jest to prosty SELECT)

Znacie może jakiś sposób, jak wykonać takie zapytanie poprawnie, albo ewentualnie sprawdzić co jest przyczyną tego że nie chce się wykonać?
Pierwszy raz spotykam się z taką sytuacją.

Z góry dziękuję za pomoc
P.

0
moraw2008 napisał(a):

Cześć,

Prośba o poradę, spotkaliście się może kiedyś z przypadkiem, kiedy zapytanie z zagnieżdżonym podzapytaniem nie zwraca błędów, jednak nie wykonuje się?

Podam na przykładzie:
Mam zapytanie o konstrukcji dosyć prostej (podaje przykład czysto koncepcyjny):

SELECT
A.parametr1,
B.parametr2,
C.parametr3
FROM tabela1 A, tabela2 B, tabela3 C
WHERE
a.id = b.id and
b.id = c.id and
c.id IN (SELECT D.id FROM tabela4 D
where warunek 1
warunek 2....itd)

Zapytanie wykonuje się w miarę szybko zwracając poprawny wynik na wszystkich bazach danych stałych (nawet tych, o bardzo dużym wolumenie danych, ORACLE 12.x).
W przypadku kiedy wykonuje je jednak na bazie danych, która podlega ciągłej aktualizacji w czasie rzeczywistym (aktualizowane są wszystkie tabele, szczególnie tabela 4)
Zapytanie wykonuje się w nieskończoność... Oracle Developer wisi w stanie (executing query) i w żaden sposób nie mogę zatrzymać tego procesu.

Wykonując dla sprawdzenia zapytanie bez podzapytania, oraz testowo samo podzapytanie otrzymuje normalnie wynik po 2-3 sekundach
Czy fakt, że baza podlega ciągłej aktualizacji i zmieniają się zawartości tabel może mieć tutaj wpływ? (nawet jeśli jest to prosty SELECT)

Znacie może jakiś sposób, jak wykonać takie zapytanie poprawnie, albo ewentualnie sprawdzić co jest przyczyną tego że nie chce się wykonać?
Pierwszy raz spotykam się z taką sytuacją.

Z góry dziękuję za pomoc
P.

Oracle nie blokuje tabel do odczytu, chyba, że ktoś ją zablokuje jawnie (LOCK TABLE X IN EXCLUSIVE MODE). Przy wykonywaniu zapytania bierze blok, który jest na dysku (i może być niespójny) i uspójnia go danymi z redo logów.

Twoje zapytanie na danej bazie może mieć jakiś dalekie od "optymalnego"/"dobrego" planu wykonania. Sprawdź jaki jest plan wykonania zapytania na "dobrej" i "wolnej" bazie.

SET LINESIZE 150
SET PAGESIZE 0
explain plan for ZAPYTANIE;
SELECT * FROM table(DBMS_XPLAN.DISPLAY);
0
moraw2008 napisał(a):

[...]
Wykonując dla sprawdzenia zapytanie bez podzapytania, oraz testowo samo podzapytanie otrzymuje normalnie wynik po 2-3 sekundach
[...]

Ale jak dokładnie to robisz? Zamiast podzapytania wrzucasz ręcznie wynik tego podzapytania? Bo od tego, ile rekordów zwraca podzapytanie zależy czas trwania całości. Zobacz na obciążonej bazie ile czasu zajmie podzapytanie i zapytanie główne z wklejonym wynikiem podzapytania.

Myślę o indeksach, czy aktualizacja danych jakoś nie utrudnia korzystania z indeksów. A jeszcze jakby były bitmapowe...

Ja też obserwuję, że na obciążonej bazie łatwe zapytania (do mocno obciążonej zapisami tabeli) potrafią się kręcić nieprzyzwoicie długo.

0

Nie uzywaj zapytan skorelowanych, napisz volatile.
Ps. nie ukrywaj joinow w where, napisz je bezposrednio - zwieksza to przejrzystosc kodu

1 użytkowników online, w tym zalogowanych: 0, gości: 1