dcooper
3.12.2007, 12:25:27
Witam,
Mam pewien problem z pobieraniem danych z MYSQL. W jednej tabeli mam jakies 180 000 rekordow, codziennie jest dopisywane po kilkaset, w sezonie nawet po kilka tysiecy.
W tej chwili musze zrobic raporty finansowe oparte na tych danych. Problem jest taki, ze jak proboje pobrac wieksza ilosc danych MySQL "siada". Zmienilem czas wykonywania skryptu, pamiec dla PHP, niestety nie wiem ktore jakie ustawienia MYSQL powienienem zmienic aby za 1 razem udalo sie pobrac np. 180 000 rekordow.
Jednym z rozwiazan jest porcjowanie danych i dzielenie na pliki (w tej chwili wszystkie dane sa konwertowane do Excela), niestety nie wiem
jak to teraz polaczyc w jeden plik:/
Czy ktos spotkal sie z podobnym problemem?
Indeo
4.12.2007, 07:39:48
Tak. Ja sie spotkałem. Ja mam miliony rekordów w bazie i moje sposoby optymalizacji to:
1) - szybkie tabele (te do analiz) myisam
2) - przemyślana struktura tabel i ich optymalizacja (indeksy)
3) - konstruowanie optymalnych zapytań - INNER JOINS są szybsze niż podzapytania. Zapytania do tabel są szybsze niż zapytania do widoków itd.
4) - skomplikowane zapytania można rozbić na kilka mniejszych (wynik wczesniejszego w tymczasowej tabeli)
5) - w przypadku analiz sprawozdawczych w firmie, które mają zazwyczaj miejsce w określonych dniach miesiąca/tygodnia można wykonać wstępne przygotowanie danych. Robi tak wiele komercyjnych systemów CRM - po zamknięciu kolejnych okresów sprzedaży tworzone są z nich statystyki, wystarczające już potem do większości analiz, chodzi o to by zbędnie nie męczyć engine bazy danych. Aplikacje są tak przemyślane aby zamknięte okresy sprzedażowe nie mogły już zmieniać swoich danych, a ewentualne korekty doliczają się do aktualnego okresu. Raz wyliczone uproszczone statystyki są już niezmienne do końca świata.
Zatem jeśli Twoje wyliczenia są złożone jako zapytania bo np. łączą kilka tabel można je przyspieszyć wykonując po zamknięciu jakiegoś okresu (albo raz dziennie) zrzut wyniku zapytania z łączonych tabel do jednej tabeli. Mógłby to być widok tylko tu chodzi o gotową tabele a nie każdorazowe składanie wszystkiego do kupy. Tabela oczywiście musi nieć odpowiednie indeksy do wyszukiwania (do łączenia już nie bo wszystkie dane są w jednej tabeli)
dcooper
4.12.2007, 13:47:45
Witam, dzieki za odpowiedz.
Mam kilka problemow z tym. Miedzy innymi takie ze to nie ja projektowalem baze danych i dane finansowe sa polaczone z zamowieniami.
Zastanawiam sie faktycznie czy nie zrobic tak jak mowisz i nie dzielic danych na okresy. Problem jest taki, ze firma dopiero sie rozwija, kobieta z ksiegowosci ma problemy z mysleniem (Angielka), wiec potrzebuje rozwiazania do pobrania danych dynamicznie.
Chwilowe rozwiazanie jest takie, ze bede generowal dane czesciami i zapisywal do plikow. Na koncu polacze wszystkie pliki w jeden i wyeksportuje do Excela.
Tyle mi przyszlo do glowy. Do piatku mam czas:)
sethir
5.12.2007, 14:19:22
Cytat(dcooper @ 4.12.2007, 13:47:45 )

Witam, dzieki za odpowiedz.
Mam kilka problemow z tym. Miedzy innymi takie ze to nie ja projektowalem baze danych i dane finansowe sa polaczone z zamowieniami.
Zastanawiam sie faktycznie czy nie zrobic tak jak mowisz i nie dzielic danych na okresy. Problem jest taki, ze firma dopiero sie rozwija, kobieta z ksiegowosci ma problemy z mysleniem (Angielka), wiec potrzebuje rozwiazania do pobrania danych dynamicznie.
Sprawdź czy prawidłowo są pozakładane indexy, ja mam bazę o wielkości około 1,5 mln rekordów źle zaprojektowałem indexy (czasy wybierania rekordów były rzędu 30 sekund) po wprowadzeniu (poprawnie) indexów spadły do 3 sekund.
Pozdrawiam
dcooper
5.12.2007, 15:06:21
Witam, czym powinienem sie kierowac? Na co powinienem zakladac indexy?
Dane potrzebuje wybierac po:
1) datach (3 rodzaje)
2) id kontrahentow
3) id kategorii
Cale zapytanie jest splecione LEFT JOIN, w zapytaniu potrzebuje pobrac dane zlecenia wraz z nazwami kontrahentow i kategorii.
na co dokladnie powinienem zalozyc indexy?
sethir
5.12.2007, 15:14:29
Cytat(dcooper @ 5.12.2007, 15:06:21 )

Witam, czym powinienem sie kierowac? Na co powinienem zakladac indexy?
Dane potrzebuje wybierac po:
1) datach (3 rodzaje)
2) id kontrahentow
3) id kategorii
Cale zapytanie jest splecione LEFT JOIN, w zapytaniu potrzebuje pobrac dane zlecenia wraz z nazwami kontrahentow i kategorii.
na co dokladnie powinienem zalozyc indexy?
Moim skromnym zdaniem to powinieneś mieć założone osobne indexy na pola po których join'ujesz.
Indeo
6.12.2007, 08:29:49
Indeksy zakładasz na wszystkich punktach, w których łączą się Twoje tabele oraz na polach po których sortujesz lub których używasz do porcjowania danych. Jeśli dwie tabele łączą sie jednym polem - zakładasz na to pole w obu tabelach indeks. Jeśli dwoma polami - zbuduj indeks złożony z obu pól. Jeśli wiesz, że pewne kombinacje indeksów są unikatowe - zakładaj indeksy unikatowe. Np. id_wykladowcy,id_sali,data,godz_lekcyjna - bo wiadomo, że jeden wykładowca może w danym czasie mieć zajęcia tylko w jednej sali. Dodawanie indeksów na ślepo - na zasadzie na wszystko nie jest dobre i może spowalniać bazę. Indeks jest jak dobra ściąga - ma tam być to co potrzebne - jak będziesz miał za dużo ściąg to sie pogubisz.
dcooper
12.12.2007, 17:59:44
A wiec tak:
1) zamowienia - 180 000 rek.
2) klienci - 150 000 rek.
3) partnerzy - klikadziesiat
Stosuje zapytania laczane np. LEFT JOIN na tych trzech tabelach. Mam porobione indeksy we wspolnych punktach.
Nadal moge pobrac za jednym razem ok 4000 rekordow.
Gdzes musi byc byk. MySQL3 ?
Czy ktos wie jakie sa roznice w wydajnosci miedzy MySQL 3 i 5?
Indeo
12.12.2007, 18:46:28
A pokaż no to zapytanie
dcooper
14.12.2007, 14:42:55
Tu nie chodzi o zapytanie. Przy nawet prostym SELECT ilosc danych do pobrania jest minimalna.
Pracowalem w innej firmie kiedys i tam nie bylo problemow z iloscia danych, a danych tez sporo.
Wiem, ze trzeba skonfigurowac odpowiednio serwer, ale nie mam do tego dostepu, ew. moge wyslac wskazowki ustawien i MOZE to zmienia.
Wiec, jezeli ktos w temacie to prosilbym o naprowadzenie. Co trzeba zmieniac w ustawieniach MySQL zeby zwiekszyc ilosc danych wyrzucanych przez baze.
Indeo
16.12.2007, 02:30:33
Bazy danych posiadają pewne mechanizmy chroniące przed fragmentacją swoich plików. Polega to na tym, że pliki danych mysql, zwłaszcza tabel innodb stale sie powiększają, a nie zmniejszają się w momencie usuwania danych. Baza raz obserwując zapotrzebowanie na przestrzeń dyskową nawet po skasowaniu danych zachowuje ją jako zajętą aby system operacyjny nie wrzucił na dysk między dane należące do mysql swoich plików fragmentujących dane - co mogłoby spowalniać pracę mysql. Niezdefragmentowany dysk i baza spowalniają pracę bazy. Taki sam mechanizm mają też np. bazy MSAccess. Spróbuj wrzucić do bazy msaccess dane i sprawdź rozmiar pliku. Potem usuń dane z tabel - rozmiar pliku sie nie zmniejszy. Jest specjalne polecenie w msaccess pozwalające "zdefragmentować" dany plik. W mysql takiego mechanizmu nie ma. Dlatego też aby wyszczuplić bazę trzeba ją wyeksportować do pliku sql i najlepiej na nowo zainstalować mysql. Zaimportowana baza będzie odchudzona. Podobny problem był kiedyś w win98 z rejestrem systemowym, który ciągle puchł. Aby przyspieszyć system można było zdefragmentować rejestr - dokładnie na takiej samej zasadzie - eksport i ponowne zaimportowanie. (ale to długo trwało :) Baza oczywiście puchnie wtedy kiedy naprzemiennie ciągle importujemy do niej duże ilości danych i je kasujemy. Dlatego do testów powinno sie używać innego serwera niż docelowy. Rozfragmentowana, kilku GB baza może nieźle zarznąć komputer.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę
kliknij tutaj.