Wpis z mikrobloga

Mam taki problem. W dużym uproszczeniu Tabela A jest pewnym słownikiem zawierającym unikalne rekordy, jest ich powiedzmy 2-3 tysiące. Tabela B zawiera ~9 mln unikalnych rekordów, a tabela C, (a w zasadzie jest to parę powiązanych tabel) wiąże typy słownikowe z tabeli A z tabelą B i przechowuje wartości tych słowników dla rekordów z tabeli B. Każdy rekord z tabeli B może być powiązany z zero lub wieloma rekordami z tabeli A ale tylko raz z danym rekordem z A, powiązanie następuje poprzez C. Tabela B z tabelą C jest w relacji jeden do wielu. Tabela B nie jest częścią aplikacji, jest to zrzut wyselekcjonowanych rekordów ale posiada PK odpowiednich rekordów z aplikacji.

I teraz tak, muszę wyciągnąć i zrzucić do Excela wszystkie rekordy z tabeli A dla których istnieje przynajmniej jedno powiązanie z dowolnym rekordem z tabeli B (~9 mln rekordów, większość prawdopodobnie nie ma żadnego powiązania z A). I muszę zrobić to dla dwóch różnych baz posiadających taką samą strukturę. Wydaje się proste, realizuję to przez SELECT z A z klauzulą EXISTS ale problem jest tak, że o ile dla jednej bazy zapytanie wykonało się w 20 minut to drugie musiałem ubić po 23 godzinach bo i tak okazało się, że dane w B są nieaktualne i trzeba je najpierw odświeżyć.

Chciałbym to zrealizować zrzucając odnalezione rekordy na bieżąco do tabeli, którą bym sobie stworzył. Dzięki temu na bieżąco widziałbym jak to idzie (jak szybko przybywają rekordy), a w razie czego mógłbym to przerwać bez konieczności rozpoczynania wszystkiego od początku.

Problem taki, że nie bardzo wiem jak to zrobić. Jest jakiś sposób żeby zapytanie wykonywało się rekord po rekordzie zamiast wykonywać się w całości przy pierwszym FETCH-u? Czy może lepiej zrobić to skryptem z dwoma kursorami? Pierwszy kursor to by był w pętli SELECT PK FROM A, a drugi przyjmowałby parametr z wartością zwróconą przez pierwszy i w przypadku %FOUND robiłby INSERTA do mojej tabelki i COMMITA. Tylko czy to nie wydłużyłoby całego procesu jeszcze bardziej? Jakieś inne pomysły?

#oracle #plsql #bazydanych #sql
  • 5
@aaandrzeeey: Nie zawołałeś :>

Explain nie jest jakiś strasznie gigantyczny, w najgorszym miejscu jest chyba z 5 mln bajtów. Ja bym bardziej winił tutaj nieaktualne statystyki czyli explain jest z dupy ale to już robota adminów. Właściwie całe zapytanie łączy się poprzez PK -> FK, a każdy FK jest u nas indexowny. Można by pokombinować z hintami żeby wymusić inne połączenie niż HASH JOIN ale przyznam szczerze, że nie jestem w
@TomaszWKS: Po pierwsze, nie brzmi to zbyt skomplikowanie (o ile C to nie jakiś kasztan), ja bym obstawiał że to problem złączenia / indexów.

Po drugie to chyba może lepiej było zacząć od B, a następnie pogrupować (bo masz wyciągnąć A)

Jeżeli ani 1 ani 2 i o ile dobrze zrozumiałem to podziałałbym na C... najpierw pogrupował względem odwołań do A i B i potem wyciągnął z tego A, to powinno
@aaandrzeeey: C to jest kasztan bo jak napisałem jest to parę tabel, tylko opisuję to jako jedną dla uproszczenia a w rzeczywistości (tak z pamięci) to B jeden do wielu D, później każdy D jeden do wielu E, później każdy E jeden do wielu F, gdzie D+E+F składa się na moje C ( ͡° ͜ʖ ͡°)

I F zawiera pewnie z kilkadziesiąt milionów rekordów uzbieranych przez kilkanaście