Od kilku godzin walczy艂em z do艣膰 nietypowym problemem, kt贸ry wreszcie uda艂o mi si臋 rozwi膮za膰, czym si臋 niezw艂ocznie chwal臋 :>
Ot贸偶 w ramach jednego z projekt贸w ETL, musia艂em zaktualizowa膰 tabel臋 docelow膮 danymi z tabeli 藕r贸d艂owej. Bez zbytniego wchodzenia w szczeg贸艂y powiem tylko, 偶e u偶y艂em do tego celu instrukcji MERGE, kt贸ra (jak wszystkie Bazyle dobrze wiedz膮) jest sprytnym z艂o偶eniem INSERT, UPDATE i DELETE.
Tabele (zar贸wno docelowa jak i 藕r贸d艂owa) mia艂y ponad 60 kolumn. Ilo艣膰 rekord贸w - nieca艂e 膰wier膰 miliona, wi臋c zasadniczo drobiazg.
Zapuszczam wi臋c tego MERGE-a, oczekuj臋, 偶e wykona si臋 w czasie oko艂o jednej sekundy. Czekam minut臋, dwie, pi臋膰...
... wypijam drug膮 kaw臋...
... wreszcie, po 62 minutach, zapytanie wysypuje si臋, z bardzo szczeg贸艂owym i wiele m贸wi膮cym komunikatem b艂臋du:
java.sql.SQLException: ORA-00600: internal error code, arguments: [13013], [5001], [4643765], [63164389], [9], [63164389], [17], [], [], [], [], []
Ki czort, my艣l臋 sobie... Zagada艂em do paru lokalnych gur贸w, ale wzruszali tylko ramionami.
My艣l臋 sobie, taki ty owaki dziadygo, pewnie nie mo偶esz prze艂kn膮膰 kt贸rego艣 z rekord贸w. Metod膮 bisekcji pr贸bowa艂em wykuma膰 kt贸ry rekord powoduje problem, ale bezskutecznie. Nawet ograniczaj膮c zapytanie do jednego rekordu, wci膮偶 dostawa艂em ten sam b艂膮d. Wyj膮tkiem by艂a sytuacja, w kt贸rej tabela docelowa by艂a pusta - w贸wczas ca艂y MERGE wykonywa艂 si臋 w 0.15 sekundy. Kolejne jednak jego uruchomienie sz艂o ju偶 w maliny.
St膮d te偶 wywnioskowa艂em, 偶e musia艂 kucn膮膰 blok UPDATE. Zn贸w zastosowa艂em metod臋 bisekcji, tym razem na zbiorze modyfikowanych kolumn. I tu pierwszy sukces: uda艂o mi si臋 wyizolowa膰 jedn膮, jedyn膮 kolumn臋, kt贸ra powodowa艂a problem. Je偶eli usun膮艂em j膮 z zapytania, ca艂o艣膰 wykonywa艂a si臋 w trymiga, niezale偶nie od ilo艣ci danych oraz kolumn. Je偶eli wstawi艂em j膮 do zapytania, rozsypywa艂o si臋 ono nawet na pojedynczym rekordzie.
Kolejnym krokiem by艂o wi臋c por贸wnanie plan贸w zapyta艅 z t膮 kolumn膮 vs bez niej. Jednak 偶adnej r贸偶nicy nie zauwa偶y艂em. Przyjrza艂em si臋 uwa偶niej definicji tabeli, i okaza艂o si臋, 偶e wszystkie inne kolumny s膮 indeksowane, a ta jedna - nie.
Pomijaj膮c zasadno艣膰 zak艂adania ponad sze艣膰dziesi臋ciu indeks贸w, za艂o偶y艂em, 偶e trzeba za艂o偶y膰 indeks i na tej jednej. Co te偶 zrobi艂em (na trzy r贸偶ne sposoby, pr贸buj膮c za ka偶dym razem uruchamia膰 MERGE), jednak bez spodziewanego rezultatu. Pomimo indeksu na tej kolumnie, MERGE wci膮偶 si臋 sypa艂.
Si臋gn膮艂em wi臋c po bro艅 ostateczn膮. Po miecz gordyjski. Po odpowiednik przycisku RESET na obudowie komputera. Wywali艂em t臋 kolumn臋 z tabeli po czym doda艂em j膮 r臋cznie od nowa.
I co?
I pomog艂o!
Cz艂owiek sp臋dza prawie dwadzie艣cia lat w r贸偶nych instytucjach edukacyjnych, a na koniec uczy si臋, 偶e 99% problem贸w da si臋 za艂atwi膰 przyciskiem RESET. Lub jego odpowiednikiem...
Je偶eli chcesz do komentarza wstawi膰 kod, u偶yj sk艂adni:
[code]
tutaj wstaw sw贸j kod
[/code]
Je偶eli zrobisz liter贸wk臋 lub zmienisz zdanie, mo偶esz edytowa膰 komentarz po jego zatwierdzeniu.