Jump to content
zarcel

[php] Pobranie Kilku Tysięcy Rekordów Z Bazy

Recommended Posts

Witam!

 

Pracujemy właśnie nad pewnym projektem i mam pewien problem. Będę potrzebował pobrać wszystkie rekordy z bazy, a zakładam, że będzie ich dużo i cośtam z każdym z nich zrobić.

Kiedyś robiłem coś podobnego i zrobiłem :

 

while(mysql_fetch_array($zapytanie)){//TUTAJ JAKIS TAM KOD}

Miałem wtedy w bazie 200 rekordów, skrypt był odpalany z crona, niestety wykonywał się tylko dla pierwszych 20 rekordów(był on dość 'duży' - łamał captche, używal curla). Moim zdaniem wykonywanie zostało ograniczone do tylu, przez zbyt długi czas wykonywania, aczkolwiek nie jestem tego pewny.

 

Jeśli ktoś ma doświadczenie z czymś takim to proszę o pomoc :)

Pomysły, kod, pseudokod, wszystko mile widziane.

Edited by zarcel

Share this post


Link to post
Share on other sites

Ale chcesz je wszystkie od razu obrobić? Trochę lipa, bo nie ma wtedy żadnej kontroli nad skryptem, a jak się coś wysypie, musisz zaczynać od nowa

 

Ja sobie dzieliłem skrypt czymś takim (mniej - więcej) - import z xml + update do bazy kilkunastu tysięcy produktów + zapis do innego xml

$tm0 = time();	//poczatkowy czas$timelimit = ini_get('max_execution_time');while(...) //for, foreach, niewazne- wiadomo{		//gdzies w petli ktora leci po rekordach...		if ((time()-$tm0)>=$timelimit - 5)	{$breakit = 1; set_time_limit($timelimit+20); }	//zmiana limitu czasu na "bezpieczny"	.	.	//kod petli	.	if($breakit == 1)	{		//tutaj redirect do tego samego pliku, z przekazanym elementem, na ktorym sie przerwalo (id, albo cos w tym stylu, getem, postem, albo najlepiej w tymczasowym pliku zapisanym na serwerze)		//redirect przez wywolanie prostego js, albo headera (w zaleznosci od potrzeb).	}}

Co by trzeba było zrobić, to ustawić sobie zapytanie, żeby pobierało paczkę danych od ostatniego elementu. Ewentualnie- automagiczny redirect przy każdym rekordzie w bazie i zaczęcie od kolejnego.

U mnie to działało bez pudła przez ponad rok i działa nadal. Pomijając drobiazgi jak popsuty czasem xml, z którego się importuje.

Share this post


Link to post
Share on other sites

Przedewszystkim - dzięki za odpowiedź.

Niezła metoda myślałem o czymś takim, ale nigdy nie zabrałem się za zrobienie. Niestety tutaj końcowi userzy są dość poszkodowani opoźnieniem, a mi zależy żeby każdy user miał wykonany kod w jak najkrótszym czasie :P I takie pytanko, czy jak odpalam coś z crona to działa JS ?

Możesz zdradzić ile trwa wykonanie skryptu dla ilu elementów ?

Share this post


Link to post
Share on other sites

To zależy od serwera.

Ok. 20-22 tysiące produktów, każdy jeszcze max 8 zdjęć, max 30 dodatkowych atrybutów, przypisanie producenta, rabatu, kosztów transportu, liczenie ceny, etc. Ogólnie - dla pojedynczego produktu od 3 do 40 zapytań.

 

Na serwie nazwa.pl skrypt się wykonywał kilka(naście) godzin przez godzinowy limit zapytań do bazy - zapytań szło ponad 700 tysięcy i trzeba było co chwilę pauzować, aż limit się odnowi. Mają dodatkowo jakieś lamerskie połączenie miedzy sql a php i każde zapytanie to ~ćwierć sekundy lag.

Aczkolwiek, na serwerze bez tego limitu lata jak dziki i po 5-7 minutach jest po wszystkim.

Na moim localhoście (c2d, giga ramu, etc) całość trwa 10 minut.

 

Co do odpalania js z crona... jeżeli na serwerze jest zainstalowana przeglądarka która obsłuży js, to można ją odpalić z crona z adresem skryptu i powinno się wszystko przeładowywać. Jeżeli nie ma, zostają headery, albo jeszcze coś innego, na co do tej pory nie wpadłem.

Aczkolwiek... na tym moim skrypcie nauczyłem się, że nie ma rzeczy niemożliwych, więc pozostaje poszukać.

Share this post


Link to post
Share on other sites

Nie, dlaczego?

exit bez argumentów kończy skrypt w miejscu, w którym ten exit jest. Następny skrypt, uruchomiony w kolejnej minucie, będzie już całkiem innym zadaniem (chyba).

W sumie, nie znam się na cronie na tyle dobrze, żeby dokładnie na Twoje pytanie odpowiedzieć. Bardzo rzadko był mi potrzebny, a już wcale taki uruchamiany co minutę, kiedy poprzednie zadanie może jeszcze działać. Co się wtedy stanie, po prostu nie wiem. Warto sprawdzić.

Share this post


Link to post
Share on other sites

Hmm nie musze czekać aż się wykona, on się będzie wykonywał zazwyczaj kilka ms, natomiast kiedy warunek bedzie prawdziwy chcialbym zeby pobral tych userow i cos dla nich zrobil, potem sie usmiercil i usunal z crona :)

Dodam, że nie wiem jak to zrobić :D

Edited by zarcel

Share this post


Link to post
Share on other sites

Rozumiem, że chcesz pobrać bardzo dużo rekordów i je obrabiać. Nie prościej pobierać i obrabiać rekordy partiami? Np po 100 rekordów?

 

SELECT * FROM baza LIMIT 0,100SELECT * FROM baza LIMIT 100,100SELECT * FROM baza LIMIT 200,100

Generalnie więc całość zamykasz w pętli while lub do-while, w warunku sprawdzasz czy wynik zapytania zwrócił chociaż jeden rekord. Jeśli tak, to wykonujesz obliczenia, potem zwiększasz limit o 100 i pętla sobie lata aż zapytanie zwróci 0 rekordów, pętla się kończy.

Wyniki możesz wyświetlać partiami w tejże pętli lub ładować do zmiennej, aby potem wyświetlić wynik końcowy lub w celu dalszej obróbki.

 

Ewentualnie walisz na początek proste zapytanie SELECT id (czy coś innego prostego) i zliczasz ilość rekordów w bazie. Następnie to samo co wyżej zamykasz w pętli FOR.

Share this post


Link to post
Share on other sites

Masz możliwość edytowania swojego pliku crona i uruchamiania samego crona z poziomu php? Jeżeli tak, to dałoby się chyba skrypt wyłączyć (gdyby uprawnienia użytkowników było w porządku). Aczkolwiek- istnieje prawdopodobieństwo, że wyłączenie skryptu przez niego samego jest zbędne... nie do końca w tym momencie rozumiem jak on dokłądnie ma działać (w którymś tam miejscu się pogubiłem).

Share this post


Link to post
Share on other sites

Ewentualnie walisz na początek proste zapytanie SELECT id (czy coś innego prostego) i zliczasz ilość rekordów w bazie. Następnie to samo co wyżej zamykasz w pętli FOR.

 

Za takie coś powiniem bić linijką po łapach. Może jednak lepsze jest select count(*) from tabela? Zliczanie powinno być wykonywane po stronie engine'u bazodanowego a nie po stronie aplikacji!

Share this post


Link to post
Share on other sites

O to dokładnie mi chodziło (count), tylko nie chciało mi się grzebać w dokumentacji, jak to dokładnie leciało.

Jak ktoś sobie zadał trud użycia Google, to znalazł to rozwiązanie.

 

Znając życie to by napisał aplikację zabijającą serwer ;]

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...




×
×
  • Create New...