Problem z obsługą dużej bazy

Mam w projekcie stosunkowo niemałą bazę danych bo zawiera ~35.000 rekordów. Problem polega na tym że gdy ma mi wyświetlić listę wszystkich rekordów, wszystko staje. Według ‘top’ mysqld tylko obciąża system w 60%-80% (procesor) a pamięci nic nie zjada w zasadzie. Jeśli rzucę w konsoli n = Obiekt.all
, to bez problemu mi wyświetli całą tą kaszanę. Jeśli jednak zrobię pętlę

Obiekt.all.each { |o| o.asocjacja.pole }

wszystko dzieje się dokładnie tak jak opisałem powyżej. Nigdy nie pracowałem z takimi dużymi bazami i nie wiem nawet z której strony się za to zabrać. Proszę przynajmniej o podpowiedź co może tutaj być powodem. Ok, właśnie więcej wyciągnąłem, po dobrych kilkunastu minutach stania w takim stania jak przerwałem pętlę wywaliło mi: IRB::Abort: abort then interrupt!!: SELECT * FROM `personal_datas` WHERE (`personal_datas`.nurse_id = 14957) LIMIT 1
Więc jednak coś działa albo baaaardzo powoli.
Co mogę zrobić żeby to działało w jakimś sensownym czasie? Co jeśli będzie trzeba wylistować np. 3/4 tej bazy przy czym każdy rekord ma jeszcze 25 rekordów asocjacyjnych (jeśli mogę to tak nazwać, mam nadzieję że wiadomo o co chodzi) w większości jeden do jeden na szczęście.

Zaraz sprawdzę czy nie przyśpieszy dodanie do tabeli t.references :personal_data w migracji dla Nurse (to jest główny obiekt). Aktualnie jest to zrobione że w migracji dla PersonalData jest t.references :nurse.

Zależy mi na tym żeby tego typu zapytania działały w jakimś rozsądnym czasie, może sprzęt na którym to testuje nie jest rewelacyjny (1,6GHz, 1024RAM) ale powinno ruszać takie pojedyncze zapytania chyba?

W skrócie: podczas iteracji dla każdego z 35k rekordów wykonywane jest jedno zapytanie do wyciągnięcia obiektu kryjącego się pod nazwą “asocjacja” (na podstawie odpowiedniego klucza obcego oczywiście).

Fix:

Obiekt.all(:include => :asocjacja)
albo
Obiekt.all(:joins => :asocjacja)

Dlaczego:

Generalnie czeka Cię trochę lektury z okolic następujących fraz: “SQL relations”, “SQL JOIN”, “N+1 queries”, “ActiveRecord include joins”, najlepiej w tej kolejności, dokładnie i kompleksowo.

Ok, dzięki bardzo, przyśpieszyło to bardzo wszystko, wiedziałem w zasadzie że coś takiego jest, ale po co albo na co, to już nie za bardzo, cóż, ciągle widzę braki u siebie, biorę się za lekturę.

A ze swojej strony dodam, że baza mająca 35k rekordów jest raczej mała i takie rzeczy powinna obsłużyć szybko. No i pytanie czy jesteś pewien, że na pewno chcesz wyciągać wszystkie rekordy, przeważnie nie ma takiej potrzeby i wtedy wszystko się robi znacznie szybciej. Napisz co dokładnie chcesz zrobić możliwe, że jest jakieś obejście. Poza tym możesz mieć też źle zrobioną bazę, brak indeksów, złą konfigurację itd.

Jestem świadom że często i większe bazy się obsługuje, jednak jak ja pierwszy raz mam do czynienia z bazą o takich rozmiarach. Cóż, robię system zarządzania bazą osób zapisanych do izby. Przy wylistowaniu wszystkich, w zasadzie nie potrzebuję dostępu do wszystkiego. Przy tworzeniu raportów, potrzebuję dostęp tylko do części asocjacji. Co do raportów, jestem w stanie sobie z tym poradzić dość szybko i łatwo, tak więc już poprawki są w drodze. Jeśli chodzi jednak o listę, przeglądanie i edycję rekordów, korzystam z ActiveScaffold i tu się schody zaczną bo będę musiał się albo przedrzeć przez kod, albo znajdę w dokumentacji jak zrobić te poprawki szybko i wygodnie.