Traf chciał, że jakiś czas temu powstał kawałek systemu, którego celem było zapamiętanie migawek większej ilości powiązanych tabel (powiązania można określić jako dwa drzewa, połączone za pomocą 2 gałęzi). Głównym powodem powstania była konieczność "zamrożenia" stanu danych na dany moment, możliwością odczytu (za pomocą SQL) kolejnych wersji.
Baza danych
AS400 - IBM - stosowana przez banki, NFZ i mafię kolumbijską. Konkretnie w wersjach od 5.2 do 6.1 (najnowsza)
Struktura:
Tabela główna A z kluczem głównym na 1 polu,
Tabela z historią H - klucz główny na 1 polu - typu DEC(12, 0)
Relacja A <- H (1 do wielu)
Zapis wszystkich danych do tabeli M
Podejście 1:
Realizacja:
Procedura składowana zrzuca dane do jednej tabeli M, gdzie pamiętamy:
a) identyfikator kolejnego uruchomienia procedury
b) typ elementu - wyliczeniowy, definiowany na zewnątrz
c) identyfikator elementu A
d) identyfikator tabeli z historią H
Problemy:
Ilość danych przerosła oczekiwania - w przypadku równoległego uruchomienia 60-100 kopii procedury ilość danych zapisywanych do 1 tabeli osiągała 1 milion rekordów na minutę - baza dawała radę, ale wszystko dookoła zdychało.
Próba rozwiązania:
Ograniczenia w ilości uruchomień, osobna pula połączeń dla procedury generującej.
Wynik:
Z powodu liniowego narastania ilości danych wydajność spadała (również liniowo) - czas wykonania jednej procedury osiągał do 2-3h.
Podejście 2.
Realizacja:
Rozbicie tabeli, do której zapisywane są dane M na wiele tabel - głównie w celu rozbicia obciążenia dysków.
Wynik:
Skok wydajności, ale o wiele mniejszy od oczekiwanego - spowodował powtórne osiągnięcie wydajności takiej jak kilka miesięcy wcześniej.
Problemy:
Ciągle liniowy spadek wydajności z czasem.
Po długiej analizie okazało się, że wiele równolegle puszczonych zapytań typu:
SELECT * FROM H
WHERE H.ID = (SELECT MAX(ID) FROM H WHERE H.ID_A = ID_A)
generuje zdumiewająco duże obciążenie procesora (wszystko po indeksach).
Podejście 3.
Realizacja:
Do tabeli A zostało dodane pole ID_H przechowujące wartość ostatniego rekordu historii.
Podczas zapisu do tabeli H pole A.ID_H jest aktualizowane.
Wynik:
Skok wydajności o około 10 000%... Uśmiechnięty i zadowolony klient, baza danych w końcu odciążona, można realizować kolejne pomysły klienta.
Fanfary, oklaski dla projektanta X (autora pomysłu 3.) , baty dla projektanta Y (autora pierwszego pomysłu), a dla programisty skrzynka piwa - za to, że musiał to wszystko kodować...