![]() |
![]() ![]() |
![]() |
![]()
Post
#1
|
|
Grupa: Zarejestrowani Postów: 28 Pomógł: 0 Dołączył: 25.10.2004 Skąd: Wrocław Ostrzeżenie: (0%) ![]() ![]() |
Witam wszystkich!
zmagam sie z problemem pobierania danych do wykresu. Chodzi o to, że użytkownik ma mozliwośc podania zakresu dat za jaki okres chce zobaczyć wykres. Danych za ten okres moze byc kilka, a może być 100milionów. Zakładam, że komponent wykresowy akceptuje powiedzmy 10000 punktów i tu pytanie: -czy mozna skonstruować takie zapytanie, aby w przypoadku gdy liczba rekordów wyniku była większa niż 100tysięcy to wtedy wyciągnie tylko co niektóre (kwestia algorytmu wyliczającego co ile punktów pobierać rekord do wyniku - np. jakiś mod) tak, żeby tabela końcowa wracająca z serwera do aplikacji miała nie wiecej niż te 100tysięcy wierszy? data zawarta w rekordach jest typu double (zmodyfikowana data julianska MJD). jesli ktoś bawił się z takim czymś to chetnie usłyszę którędy droga ![]() pozdrawiam Ten post edytował ky3orr 29.03.2009, 01:56:47 -------------------- yegomość KY3ORR
|
|
|
![]()
Post
#2
|
|
![]() Grupa: Moderatorzy Postów: 15 467 Pomógł: 1451 Dołączył: 25.04.2005 Skąd: Szczebrzeszyn/Rzeszów ![]() |
Cytat Danych za ten okres moze byc kilka, a może być 100milionów. Może where na resztę z dzielenia przez jakis warunek? Cytat tak, żeby tabela końcowa wracająca z serwera do aplikacji miała nie wiecej niż te 100tysięcy wierszy? No to pozostaje chyba generowanie liczb losowych w zależności od liczby; order by rand() jest zbyt czasochłonne. -------------------- ![]() ZCE :: Pisząc PW załączaj LINK DO TEMATU i TYLKO w sprawach moderacji :: jakiś błąd - a TREŚĆ BŁĘDU? :: nie ponaglaj z odpowiedzią via PW! |
|
|
![]()
Post
#3
|
|
![]() Grupa: Moderatorzy Postów: 36 557 Pomógł: 6315 Dołączył: 27.12.2004 ![]() |
najpierw zliczasz ile masz wszystkich wierszy (zwykly select count(*))
jesli malo, to generujesz zapytanie co pobiera wszystkie jesli duzo to generujesz zapytanie co pobiera co n-ty. tu masz przyklad na takie zapytanie: http://nospor.pl/mysql-faq-n25.html#faq-7 -------------------- "Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista "Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer |
|
|
![]()
Post
#4
|
|
![]() Grupa: Zarejestrowani Postów: 744 Pomógł: 118 Dołączył: 14.02.2009 Skąd: poziome Ostrzeżenie: (0%) ![]() ![]() |
nospor->Malo optymalnie:
wystarczy zwykle zapytanie select * from stats order by date sprawdzenie ile zwrocilo rekordow: mysql_num_rows($uchwyt_do_zapytania) pozniej sprawdzasz if($ilosc_rekordow>100000) $step=round($iloscrekordow/100000); else $step=1; i na koniec w while($dane=mysq_fetch_array( $uchwyt_do_zapytania)){ mysql_data_seek($uchwyt_do_zapytania, $pozycja+$step); $pozycja=$pozycja+$step; } * to jest tylko szkic logiczny ale przedstawia co trzeba uzyc i jak -------------------- śmieszne obrazki
Kryzys: Ser jem spleśniały, wino piję stare i samochód mam bez dachu.. |
|
|
![]()
Post
#5
|
|
![]() Grupa: Moderatorzy Postów: 15 467 Pomógł: 1451 Dołączył: 25.04.2005 Skąd: Szczebrzeszyn/Rzeszów ![]() |
~maly_swd, niby czemu? Twój przykład zeżre dużo więcej zasobów (przede wszystkim pamięci) niż ~nospora.
-------------------- ![]() ZCE :: Pisząc PW załączaj LINK DO TEMATU i TYLKO w sprawach moderacji :: jakiś błąd - a TREŚĆ BŁĘDU? :: nie ponaglaj z odpowiedzią via PW! |
|
|
![]()
Post
#6
|
|
![]() Grupa: Moderatorzy Postów: 36 557 Pomógł: 6315 Dołączył: 27.12.2004 ![]() |
Cytat nospor->Malo optymalnie: yyy, opierasz swoją teorie na doswiadczeniach? To szybko lec i poprawiaj kody, które do tej pory napisales ![]() -------------------- "Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista "Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer |
|
|
![]()
Post
#7
|
|
![]() Newsman Grupa: Moderatorzy Postów: 4 005 Pomógł: 548 Dołączył: 7.04.2008 Skąd: Trzebinia/Kraków ![]() |
~maly_swd stworzyłeś jakiegoś potworka pamięciożernego. nie ma nic lepszego od przerzucenia liczenia na serwer SQL.
-------------------- |
|
|
![]()
Post
#8
|
|
Grupa: Zarejestrowani Postów: 28 Pomógł: 0 Dołączył: 25.10.2004 Skąd: Wrocław Ostrzeżenie: (0%) ![]() ![]() |
nospor dzięki za linka.
teraz muszę rozkminić jak to działa, ale jest trop ![]() jak sobie poradzę z tematem przedstawię receptę w wątku. pozdrawiam Ten post edytował ky3orr 30.03.2009, 22:12:47 -------------------- yegomość KY3ORR
|
|
|
![]()
Post
#9
|
|
![]() Grupa: Zarejestrowani Postów: 744 Pomógł: 118 Dołączył: 14.02.2009 Skąd: poziome Ostrzeżenie: (0%) ![]() ![]() |
Twoj sposob jest dobry pod warunkiem ze znamy STEP.
*tak moj przyklad jest poparty doswiadczeniem i testami na tabelach po 10-20milionow rekordow -------------------- śmieszne obrazki
Kryzys: Ser jem spleśniały, wino piję stare i samochód mam bez dachu.. |
|
|
![]()
Post
#10
|
|
![]() Grupa: Moderatorzy Postów: 36 557 Pomógł: 6315 Dołączył: 27.12.2004 ![]() |
Cytat Twoj sposob jest dobry pod warunkiem ze znamy STEP. No bo przeciez znamy. Jesli masz x rekordow a chcesz sobie wyswietlic z nich tylko y gdzie y < x to wyliczenie step to podstawa matematyki ktorej w podstawowce ucząCytat *tak moj przyklad jest poparty doswiadczeniem i testami na tabelach po 10-20milionow rekordow ![]() Chcesz policzyc ile rekordow ma baaaardzo duza tabela. Ta bardzo duuuza tabela ma 20mln rekordow i ty w tym celu pobierasz z bazy danych wszystkie 20 mln rekordow..... mistrzu, jestes wielki.... tak samo wielki jak optymalny twoj skrypt ![]() edit: wykonaj sobie najpierw taki kod
zmierz ile skrypt zajął pamięci, jak długo sie wykonywał następnie wykonaj taki kod
zmierz ile skrypt zajął pamięci, jak długo sie wykonywał porównaj uzyskane wyniki ze sobą i przestan wkońcu wypisywac glupoty.... ps: twojabardzoduzatabela to tabela, która ma te pare mln rekordów. -------------------- "Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista "Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer |
|
|
![]()
Post
#11
|
|
Grupa: Zarejestrowani Postów: 28 Pomógł: 0 Dołączył: 25.10.2004 Skąd: Wrocław Ostrzeżenie: (0%) ![]() ![]() |
nospor czy, aby wykonać ten zestaw poleceń:
Cytat SET @nr=-1, @coile=5; select * from ( select @nr:=@nr+1 _nr,tabela.* from tabela ) jakisalias where _nr % @coile = 0; trzeba zamknąć je w jakąś procedurę czy funkcję? próbowałem przetestować to w SQL Query Browserze z pakietu MySQL GUI Tools i klumna która powinna być numerowana zwróciła mi NULLe. podejżewam, że linia z setem i zapytanie wykonały sie niezależnie... pozdrawiam Ten post edytował ky3orr 31.03.2009, 09:53:04 -------------------- yegomość KY3ORR
|
|
|
![]()
Post
#12
|
|
![]() Grupa: Moderatorzy Postów: 36 557 Pomógł: 6315 Dołączył: 27.12.2004 ![]() |
SET to jedno zapytanie
kolejne linie to następne jedno zapytanie. One powinny byc wykonane jedno po drugim. W php bedą to poprostu dwa mysql_query() po sobie. Nie wiem jak to realizuje twoj SQL Query Browser Przykladowo sqlyog ktorego uzywam ma opcje wykonywania zapytan jako calosci i dziala ok. -------------------- "Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista "Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer |
|
|
![]()
Post
#13
|
|
![]() Grupa: Przyjaciele php.pl Postów: 5 724 Pomógł: 259 Dołączył: 13.04.2004 Skąd: N/A Ostrzeżenie: (0%) ![]() ![]() |
@ky3orr: Query Browser pod tym wzgledem to gowno, nie potrafi wykonac kilku SQLek oddzielonych srednikiem, wiec musisz wrzucac zapytania (dwa) pojedynczo do JEDNEGO taba.
Uzyj phpMyAdmin - tam takie cos dziala - wrzuc wszystkie zapytania od razu. -------------------- Nie lubię jednorożców.
|
|
|
![]()
Post
#14
|
|
![]() Grupa: Zarejestrowani Postów: 744 Pomógł: 118 Dołączył: 14.02.2009 Skąd: poziome Ostrzeżenie: (0%) ![]() ![]() |
nospor-> widze ze nie zrozumiales tego co napisalem (szkoda). Jest tam napisane ze jest to szkic. W przypadku jak nie znamy ile baza ma rekordow (nie wykonujemy wczesniej select count(*)...
tylko mamy np select id, text, pole from tabela where pole='cos' (bo takie wyniki chcemy dostac) i wyciagnac z tego 120 rekordow (nie piwrwszych - tylko z STEP x) Takie zapytanie wykona sie szybko i nie pobierasz wszystkich rekordow do PHP. Druga sprawa ze taki wynik jest cachowany przez mysqla. -------------------- śmieszne obrazki
Kryzys: Ser jem spleśniały, wino piję stare i samochód mam bez dachu.. |
|
|
![]()
Post
#15
|
|
![]() Grupa: Moderatorzy Postów: 15 467 Pomógł: 1451 Dołączył: 25.04.2005 Skąd: Szczebrzeszyn/Rzeszów ![]() |
Cytat Druga sprawa ze taki wynik jest cachowany przez mysqla. No właśnie. CAŁY WYNIK, a nie tylko liczba rekordów. Poza tym, wykonanie dodatkowego zapytania nieraz się bardziej opłaca. A jeśli już chcesz na upartego liczyć wyciągnięte: Cytat sprawdzenie ile zwrocilo rekordow: mysql_num_rows($uchwyt_do_zapytania) Użycie tej funkcji jest odradzane, poczytaj trochę, to porozmawiamy. Jeśli już chcesz tak liczyć rekordy, to poszukaj o SQL_CALC_FOUND_ROWS. -------------------- ![]() ZCE :: Pisząc PW załączaj LINK DO TEMATU i TYLKO w sprawach moderacji :: jakiś błąd - a TREŚĆ BŁĘDU? :: nie ponaglaj z odpowiedzią via PW! |
|
|
![]()
Post
#16
|
|
![]() Grupa: Moderatorzy Postów: 36 557 Pomógł: 6315 Dołączył: 27.12.2004 ![]() |
Cytat nospor-> widze ze nie zrozumiales tego co napisalem (szkoda). No sorki, ale napisales dosc wyraźnie: Cytat wystarczy zwykle zapytanie select * from stats order by date Inaczej tego raczej rozumiec nie mozna sprawdzenie ile zwrocilo rekordow: mysql_num_rows($uchwyt_do_zapytania) ![]() Cytat pozniej sprawdzasz if($ilosc_rekordow>100000) $step=round($iloscrekordow/100000); else $step=1; i na koniec w while($dane=mysq_fetch_array( $uchwyt_do_zapytania)){ mysql_data_seek($uchwyt_do_zapytania, $pozycja+$step); $pozycja=$pozycja+$step; Przeciez ty wtym przykladzie ewidentnie pobierasz z mysql wszystkie 20mln rekordow a dopiero potem stepem w php pobierasz tylko co ktorys. Zorientowales sie dopiero teraz ze sie myliles i starasz sie odwrocic kota ogonem choc i to ci nie wychodzi. weź wykonaj te dwa przyklady co ci podalem pare postow wczesniej to moze wkoncu do ciebie dotrze w jak wielkim bledzie jestes Jesli tego nie zrobisz, dalsza dyskusja wydaje sie raczej zbedna Cytat i wyciagnac z tego 120 rekordow zauwaz ze my tu mowimy o tabeli ktora ma liczbę rekordow liczoną w milionach i chcemy z tego wyciągnac 100tys a nie nedzne 120 rekordów
-------------------- "Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista "Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer |
|
|
![]()
Post
#17
|
|
Grupa: Zarejestrowani Postów: 28 Pomógł: 0 Dołączył: 25.10.2004 Skąd: Wrocław Ostrzeżenie: (0%) ![]() ![]() |
Koledzy!
nie było moją intencją skłócić kogokolwiek zakładając tgen temat, jednak czytając cały topic wiele można sobie uświadomić o istocie pamięciożerności przez tgen czy tantan styl zapytań. Puki co staram się ujarzmić kilka zapytań jednocześnie ![]() pozdrawiam -------------------- yegomość KY3ORR
|
|
|
![]()
Post
#18
|
|
Grupa: Zarejestrowani Postów: 592 Pomógł: 62 Dołączył: 3.08.2006 Ostrzeżenie: (0%) ![]() ![]() |
maly_swd, a czy czasem mysql_num_rows nie przelatuje wszystkiego jeszcze raz?
![]() -------------------- :]
|
|
|
![]()
Post
#19
|
|
![]() Grupa: Moderatorzy Postów: 36 557 Pomógł: 6315 Dołączył: 27.12.2004 ![]() |
Cytat Puki co staram się ujarzmić kilka zapytań jednocześnie Z racji, ze przeprowadzilem sobie wewnetrzny test, to masz juz gotowy kod:
A oto wynik: Ilosc wszystkich rekordow:6359961 Co ile:64 Ilosc przetworzonych rekordow:99375 Czas 7.34749293327 A tutaj kod w wersji maly_swd:
I wynik: Ilosc wszystkich rekordow:6359961 Co ile:64 Fatal error: Maximum execution time of 990 seconds exceeded Jak widac tabela ma ponad 6 mln rekordow. Dla mojej wersji skrypt wykonywał sie 7 sekund. Procesy systemowe w normie, podkoczyl jedynie troche proces mysql ale nie zuzywal wcale wiecej pamieci niz normalnie. Dla wersji malego skrypt wykonywal sie koszmarnie dlugo. Proces apachea wskoczyl mi na maxa i zajął ponad 300MB pamieci. Dodatkowo nie doczekalem sie na wynik. Musialem sztucznie zwiększyc $coIle na 20000 by doczekac sie wyniku. Oto on: Ilosc wszystkich rekordow:6359961 Co ile:20000 Ilosc przetworzonych rekordow:317 Czas 20.1107699871 PRzykladowo moj skrypt dla tej wartosci $coIle uzyskal nastepujace wyniki Ilosc wszystkich rekordow:6359961 Co ile:20000 Ilosc przetworzonych rekordow:318 Czas 7.14381098747 Wnioski: no chyba nie musze mowic.... ![]() @maly_swd jesli naprawde myslales o innym rozwiązaniu to prosze podaj je dokladnie. Jesli jednak nie, to moze wkoncu przyjmiesz fakty do wiadomosci. edit: a, i jeszcze wyniki moich wczesniej podanych skryptow dla tej samej tabeli z 6 mln rekordow czas dla select count(*): 0.00517010688782 czas dla mysql_num_rows: 6.46986794472 no comments.... ![]() -------------------- "Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista "Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer |
|
|
![]()
Post
#20
|
|
![]() Newsman Grupa: Moderatorzy Postów: 4 005 Pomógł: 548 Dołączył: 7.04.2008 Skąd: Trzebinia/Kraków ![]() |
robiąć tak jak napisał ~maly_swd można w piękny sposób zajechać PHP. i nawet przy tych nędznych 120 rekordach będzie widoczna różnica. jak że sprawa wymaga testów przeprowadziłem takowe, wyniki:
i wyniki: Kod 0.56250300 1238533233 0.56390500 1238533233 0.001402 testowane na 222 rekordach przy 100 tyś będzie proporcjonalnie więcej... -------------------- |
|
|
![]() ![]() |
![]() |
Wersja Lo-Fi | Aktualny czas: 14.08.2025 - 00:22 |