Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP][MYSQL] Jak to przyspieszyć?
Forum PHP.pl > Forum > PHP
busterek
Mam taki prosty skrypt:

  1. <?php
  2.  
  3. $con = mysql_connect('localhost', 'user', 'haslo');
  4. mysql_select_db('mailing');
  5.  
  6.  
  7. $file = file('/srv/www/newmailing/log2');
  8.  
  9. foreach ($file as $line)
  10. {
  11. $data = explode(' -> ', $line);
  12. $mail = $data[1];
  13. $query = 'update emails set sent = "1" where sent = "0" and email = "'.$mail.'";';
  14. mysql_query($query);
  15. }
  16. ?>


W zaczytywanym pliku jest ponad 330.000 linii. Czy da się to jakoś przyśpieszyćquestionmark.gif Bo działa to sakramencko wolno. wink.gif
nospor
1) Mozesz wywalic z warunku
sent = "0"

2) zalozyc index na pole email

3) Oraz by nie wykonywac 330k zapytan do bazy, podzielic to na paczki, np po 1000 i bedzie tylko 330 zapytan smile.gif
busterek
Najbardziej mnie interesuje ten punkt 3.

Myślałem o tym, ale nie za bardzo wiem jak to ugryźć. Weź podpowiedz jakoś. Jak jednym zapytaniem zmienić 1000 rekordów?
Pyton_000
Po pierwsze wywal te mysql_* i zamień choćby na mysqli lub PDO.

Może tak będzie szybciej:

Kod
CREATE TEMPORARY TABLE temptable (
  email VARCHAR,
  INDEX (email)
) ENGINE = MEMORY;

LOAD DATA LOCAL INFILE '/srv/www/newmailing/log2' INTO temptable (column2) FIELDS TERMINATED BY ' -> ';

UPDATE emails JOIN temptable USING(email) SET sent = "1" WHERE sent = "0" AND emails.email = temptable.email;

DROP TEMPORARY TABLE temptable;
Spawnm
Sprawdz where email in ($maile)

//edit
Pyton dal chyba najciekawsze rozwiazanie
busterek
Właśnie próbuję wykonać kod pokazany przez Pytona. Ale nie wiem co jest. Tabelę dodaje. Ładowanie pliku musiałem przerobić na taką linijkę, bo ta która jest w przykładzie zgłasza błąd w składni.

  1. LOAD DATA LOCAL INFILE '/srv/www/newmailing/log2' INTO TABLE temptable FIELDS TERMINATED BY ' -> ';


Ale po wykonaniu otrzymuję błąd: ERROR 2013 (HY000): Lost connection to MySQL server during query

Co jest nie tak?
Pyton_000
to co wywaliłeś było potrzebne aby do tabeli załadować tylko kolumnę z mejlami. Inaczej musisz stworzyć temptable z 2 kolumnami. Co do składni i błędu bardzo możliwe, nie testowałem tego, tak tylko na szybko.

Gdzie odpalasz te zapytania?
busterek
Zapytania odpalam bezpośrednio w konsoli mysql-a.
Pyton_000
Po zalogowaniu do Mysql odpal jeszcze:

Kod
SET wait-timeout=3600;
SET max-allowed-packet=419430400;

i ponownie spróbuj
busterek
Ruszyło. Natomiast teraz problem z UPDATE. Zapytanie się wykonuje, ale nic nie zmienia.
Pyton_000
Sprawdź czy zawartość w temptable jest odpowiednia np:

Kod
SELECT CONCAT('"', emails, '"') FROM temptable;

bo możliwe że są tam jakieś białe znaki które nie łączą się w pary z mejlami z mejls.
busterek
No tak. W pliku nie ma białych znaków. Ale w głównej tabeli już są. Ehhhh. To już wiem co zrobić.

---Albo i nie wiem. wink.gif
Pyton_000
TRIM(emails.email) = TRIM(temptable.email)
busterek
No tak. Wykonuję takie zapytanie. W zasadzie składnia jest poprawna i powinno działać. Ale nie działa.

  1. UPDATE emails JOIN temptable USING(email) SET sent = "1" WHERE trim(BOTH "\n" FROM emails.email) = temptable.email;


Zapytanie się wykonuje, ale nic nie zmienia. Czy może coś źle jest?

A sprawdziłem jak wygląda kolumna email w tabeli emails po wykonaniu tego TRIM-a. I jest ok, bez białych znaków. W temptable też nie ma białych znaków.

Udało się. Trochę na około, bo miałem błędy w danych. Ale udało się. Dzięki za pomoc.
Pyton_000
Pochwal się wynikiem. Jaki czas?
busterek
Kurcze. Nie spojrzałem, ale chyba coś koło 45 sekund. Błyskawica. wink.gif
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.
Invision Power Board © 2001-2025 Invision Power Services, Inc.