Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> [PHP][MySQL] Problem z pobieraniem dużej ilości danych
progresmedia
post
Post #1





Grupa: Zarejestrowani
Postów: 30
Pomógł: 1
Dołączył: 7.05.2009
Skąd: Wrocław

Ostrzeżenie: (0%)
-----


Witam,

mam następujący problem:

chcę wyświetlić trochę rekordów z bazy i teraz tak:

jeżeli wyświetlam do 2000 rekordów to wszystko jest OK.

Jeżeli chcę wyświetlić > 2000 rekordów, wyskakuje komunikat:

Kod
<h1>Internal Server Error</h1>  The server encountered an internal error or misconfiguration and was unable to complete your request


Znacie może jakiś sposób na obejście tego?

Próbowałem zwiększyć 'max_execution_time', ale niestety efekt został ten sam.

Od razu mówię że wolałbym uniknąć porcjowania zapytań i chciałbym wyświetlić wszystkie rekordy na jednej stronie.

Ten post edytował progresmedia 23.08.2009, 14:22:27


--------------------
<aL> jaką masz stronę startową?
<Gustaff> na firefox'ie wp.pl...
<Gustaff> a na IE about:blank, żebym wiedział, że złą przeglądarkę włączylem ;P

www.progresmedia.pl
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 7)
Spawnm
post
Post #2





Grupa: Moderatorzy
Postów: 4 069
Pomógł: 497
Dołączył: 11.05.2007
Skąd: Warszawa




albo set_time_limit(); albo zrób pager .
Go to the top of the page
+Quote Post
progresmedia
post
Post #3





Grupa: Zarejestrowani
Postów: 30
Pomógł: 1
Dołączył: 7.05.2009
Skąd: Wrocław

Ostrzeżenie: (0%)
-----


Próbowałem set_time_limit(), bez efektu.

Pager? A dokładniej?smile.gif


--------------------
<aL> jaką masz stronę startową?
<Gustaff> na firefox'ie wp.pl...
<Gustaff> a na IE about:blank, żebym wiedział, że złą przeglądarkę włączylem ;P

www.progresmedia.pl
Go to the top of the page
+Quote Post
Spawnm
post
Post #4





Grupa: Moderatorzy
Postów: 4 069
Pomógł: 497
Dołączył: 11.05.2007
Skąd: Warszawa




pager/paginacja/stronicowanie ... dzielenie treści na strony ...
Go to the top of the page
+Quote Post
progresmedia
post
Post #5





Grupa: Zarejestrowani
Postów: 30
Pomógł: 1
Dołączył: 7.05.2009
Skąd: Wrocław

Ostrzeżenie: (0%)
-----


No właśnie tego chcę uniknąć.


--------------------
<aL> jaką masz stronę startową?
<Gustaff> na firefox'ie wp.pl...
<Gustaff> a na IE about:blank, żebym wiedział, że złą przeglądarkę włączylem ;P

www.progresmedia.pl
Go to the top of the page
+Quote Post
thek
post
Post #6





Grupa: Moderatorzy
Postów: 4 362
Pomógł: 714
Dołączył: 12.02.2009
Skąd: Jak się położę tak leżę :D




W pierwszym poście napisał, że nie chce porcjować zapytania, więc stronnicowanie raczej odpada. Ja bym się zastanawiał nad ustawianiem jednak set_time_limit co jakiś określony czas ( co ileś iteracji ) wewnątrz pętli. Teoretycznie powinno to resetować licznik działania skryptu. Stwarza też narzut czasowy niestety. Z każdą iteracją bowiem byłby if i inkrementacja jakiegoś licznika, czyli minimum 2 dodatkowe cykle zegara co przejście pętli. Mało w porównaniu do całości czasu trwania skryptu, więc można się skusić i sprawdzić. Choć myślę, że jednak bez jakiegoś sensownego ograniczenia liczby rekordów nie ma co tego ruszać, bo obejście max_execution_time bez porcjowania, choćby niejawnego nie jest możliwe. Ja w newsletterze dla dużej liczby użytkowników zrobiłem rekurencję gdzie skrypt wywoływał sam siebie po pewnym czasie, ale tego typu rozwiązanie jest bezsensowne tutaj.


--------------------
Najpierw był manual... Jeśli tam nie zawarto słów mądrości to zapytaj wszechwiedzącego Google zadając mu własciwe pytania. A jeśli i on milczy to Twój problem nie istnieje :D
Go to the top of the page
+Quote Post
progresmedia
post
Post #7





Grupa: Zarejestrowani
Postów: 30
Pomógł: 1
Dołączył: 7.05.2009
Skąd: Wrocław

Ostrzeżenie: (0%)
-----


Próbowałem już set_time_limit(), zrobiłem coś takiego:
Kod
    ini_set('max_execution_time', 1000);
    $sql = mysql_query("SELECT newsletter_id, email FROM wp_newsletter_baza ORDER BY newsletter_id DESC");
    while(list($newsletter_id, $email) = mysql_fetch_row($sql)) {
        /* KOD */
        $b++;
        if($i == 4) {
            ?></tr><tr><?
            $i = 0;
        }
        if($b == 500) {
            set_time_limit(120);
            $b = 1;
        }
    }


Jednak skrypt na to nie reaguje (dalej pojawia się błąd).


--------------------
<aL> jaką masz stronę startową?
<Gustaff> na firefox'ie wp.pl...
<Gustaff> a na IE about:blank, żebym wiedział, że złą przeglądarkę włączylem ;P

www.progresmedia.pl
Go to the top of the page
+Quote Post
thek
post
Post #8





Grupa: Moderatorzy
Postów: 4 362
Pomógł: 714
Dołączył: 12.02.2009
Skąd: Jak się położę tak leżę :D




Skoro to wysyłanie newslettera, co podejrzewałem, to najlepiej dać sobie spokój z wyświetlaniem czegokolwiek na ekranie i poporcjować dane w rekurencji oraz zapomnieć, że się odpaliło skrypt, a najlepiej uruchamiać go w nocy cronem.
Ja mam mniej więcej tak to rozwiązane:
W bazie mam przy użytkowniku newslettera pole, będące datą, kiedy ostatnio skrypt newslettera próbowałem na nim wykonać, sam skrypt puszczam codziennie, ale mogę i nawet co 10 minut, bo nie leci po całej bazie w takim wypadku.

Plik 1:
Kod
a) ignoruję zakończenie połaczenia przez usera ( odpalam crona, a nie przeglądarkę ) - ignore_user_abort(true);
b) Pobieram z bazy pakiet X userów newslettera, którzy mają datę (Y-m-d) mniejszą niż obecna,
c) w razie braku userów killuję skrypt exitem
d) wysyłam im maile,
e) update daty na dzisiejszą robię tym z paczki pobranym,
f) opcjonalnie mogę skillować ale nie jest to potrzebne.


Jak widać w takiej sytuacji nigdy tego samego dnia nie trafię dwa razy tego samego usera bo po każdym przejściu zmniejsza mi się liczba userów z datą mniejszą od obecnej, aż do momentu, gdy nie ma juz nikogo takiego. To ważne, bo bez update'u pola daty, skrypt w rekurencji wykonywałby się w nieskończoność, wciąż dla tych samych X użytkowników.

Plik 2:
  1. if(!$id = mysql_connect('host','user','pass'))
  2. die('Błąd połączenia do bazy danych MySQL.');
  3. mysql_query("SET CHARSET charset;");
  4. $result = mysql_fetch_array( mysql_query( "SELECT count( user ) AS ile FROM newsletter WHERE data < CURDATE() ") );
  5. if($result['ile'] == 0 ) {
  6. $handle = fopen('newsletter.log','a');
  7. fwrite($handle, date('Y-m-d')." Koniec wysyłki newslettera.<br />");
  8. fclose($handle);
  9. } else {
  10. sleep(x sekund);
  11. file_get_contents('ścieżka_do_pliku_pierwszego');
  12. file_get_contents('ścieżka_do_pliku_drugiego_czyli_tego');
  13. }

Jak widać ustawiam na wszelki wypadek set time limit i user abort, łączę się z bazą i pobieram liczbę userów z datą mniejsza niż aktualna. Jeśli jest w wyniku jest zero zapisuję sobie w logu, że skrypt w tym dniu się zakończył. Jeśli jest takich userów więcej, to usypiam skrypt na ileś sekund, po czym wywołuję skrypt wysyłki porcji maili i... samego siebie oraz killuję tę instancję. W efekcie działa już kolejny "wątek" w rekurencji aż do momentu, gdy serwer nie przetworzy wszystkich rekordów. Aby to zauważyć nie można polegać na przeglądarce, gdyż ona po pewnym czasie zamknie połączenie z serwerem i wywali, że skrypt przekroczył czas, gdyż widzi ona tylko wywołanie pierwszej instancji, która już zapewne skillowana została i działa już w tle przynajmniej 2 lub 3 winksmiley.jpg Najlepiej sobie logować do pliku na serwerze poczynania skryptu, czyli albo w pliku1 lub w warunku else pliku2 coś wpisywać do loga smile.gif Ja testowałem poprzez wpisywanie do niego czasu. Działał on znacznie przekraczając owe 30s i działał wiele minut zanim zakończył działanie, gdyż ustawilem dłuższy czas w sleepie by nie zajechać serwera i dawać mu czas na wykonywanie innych działań. Ważne jest by dobrze napisać kod w plik1, bo zastosowanie rekurencji takiej jak pokazałem uruchamia co chwilę skrypt, którego serwer nie ma jak zatrzymać, gdyż spełnia wszystkie warunki nieprzekraczalności czasu wykonania wywołując się w kolejnych wątkach. Jeśli ktoś więc nie napisze go dobrze i nie przetestuje na localu to może mieć niemiłą niespodziankę na serwerze publicznym.


--------------------
Najpierw był manual... Jeśli tam nie zawarto słów mądrości to zapytaj wszechwiedzącego Google zadając mu własciwe pytania. A jeśli i on milczy to Twój problem nie istnieje :D
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 22.08.2025 - 07:16