Mar 19
Chwała tablicom! Czyli o tym jak można przyspieszyć rzeczy :)
Miałem za zadanie zrobić import jakiś danych o uzytkownikach z pliku tekstowego. Użytkowników w bazie już miałem (jakieś 50k rekordów), import miał za zadanie uzupełnić ich dane.
Parsowanie pliku było dość banalne. Poboierałem z niego dane (login i reszta danych), później pobierałem z bazy id usera (po loginie) i robiłem resztę rzeczy. Wszystko było super, aż do momentu odpalenia. Plik z danymi był spory, ale po pół godziny pracy import nadal się nie zakończył!
Zastanawiałem się jak to przyspieszyć. Przypomniała mi się rzecz, o której tyle razy przypominał Dooshek - użycie tablic. Na czym polega cały myk? Otóż na początku pobierałem wszystkie loginy i id userów i zapisywałem do tablicy w formacie [login] => [uid]. Podczas importu danych z pliku sprawdzałem id usera z tablicy przez co pół godzinny import wykonał się nagle w 30sek. :)
Warto o tym szczególe pamiętać. Ja już któryś raz z rzędu o tym zapomniałem, a szkoda. Straciłem trochę czasu na optymalizację mojego importu.
Przy zawrotnej liczbie rekordów pewnie nie będzie warto robić takiej tablicy (ponieważ zje zasoby :) ), ale przy jakiejś mniejszej liczbie myślę, że warto.

April 2nd, 2009 at 07:50
Do importu zwyczajowo wystarcza MySQLowe LOAD DATA. ( http://dev.mysql.com/doc/refman/5.1/en/load-data.html ). Podejrzewam, że będzie jeszcze szybsze. Importowaniem tego typu danych powinno być z plików CSV. A jeśli chodzi o wykluczenie duplikatów, to opcja “IGNORE” (podobnie jak w INSERT INTO) sprawi, że rekordy z indeksem UNIQUE trafią do niej tylko raz, gdy faktycznie będą unikalne (żadnego wyszukiwania czy aby ten rekord już jest :-) ). A jeśli już chce się importować dużo insertów, to zawsze można zrobić multi-insert: INSERT IGNORE INTO tbl_name (a,b,c) VALUES(1,2,3),(4,5,6),(7,8,9); W tym przypadku wstawia 3 rekordy. (więcej: http://dev.mysql.com/doc/refman/5.1/en/insert.html )
Tak więc, grunt to dobre indeksy w tabeli i poprawnie spreparowane CSVy.
Pozdrawiam,
Rafał.