Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MySQL] INSERT około 5mln rekordów to możliwe?
Forum PHP.pl > Forum > Bazy danych > MySQL
termin
Witam, chcę wybrać z bazy MS SQL-a rekordy i wrzucić je do MySQL-a na którym stoi cały sklep internetowy. Problem w tym ze w jednej tabeli jest ponad 5 mln rekordów i tak się zastanawiam jak to najlepiej zrobić. Aktualizacja tej tabeli będzie następować raz na dzień w nocy wiec z czasem nie ma tu problemu.
Zrobiłem select z ms sql i od razu insert do mysql ale po chwili wyskoczył błąd ze php nie jest w stanie zadeklarować tak dużej ilości danych.
  1. Fatal error: Allowed memory size of 524288000 bytes exhausted (tried to allocate 8715264 bytes) in ......


czy ktoś kiedyś dokonywał takich duzych operacji i może się podzielić widzą jak to najlepiej zrobić?
patryczakowy
Najlepiej etapami na przykład pięć razy po milionie
posiadacz
Na pewno nie rób tego przez apache tylko z basha. Ja bym ograniczył zapytanie np do 10 000 i wywoływał w niewielkich odstępach czasu ( po prostu sleep i kolejna partia), nawet w nocy warto dać odsapnąć bazie na kilka chwil gdyby jakiś zabłąkany user chciał coś kupić.
termin
hmm, problem w tym ze MS SQL nie ma czegoś takiego jak LIMIT i nie wiem jak wybrać dane w partiach po 10.000 rekordów
posiadacz
Sorry, nie wiedziałem.

  1. DECLARE @Sort /* the type of the sorting column */
  2. SET ROWCOUNT @StartRow
  3. SELECT @Sort = SortColumn FROM TABLE ORDER BY SortColumn
  4. SET ROWCOUNT @PageSize
  5. SELECT ... FROM TABLE WHERE SortColumn >= @Sort ORDER BY SortColumn

Znalazłem to tu: http://www.codeproject.com/kb/aspnet/PagingLarge.aspx
termin
dzięki za te wskazówki. A tak przy okazji, zauważyłem że jeśli w pętli puści się zapytanie do MySQL-a INSERT INTO to on najpierw wykona petlę np. 100 INSERTÓW trzymając to w pamięci, a dopiero potem faktycznie dodaje to do MySQL. Co trzeba by zrobić aby np. dodawał to faktycznie do bazy po każdym przejściu pętli? robiłem COMMIT ale nic to nie daje.
prachwal
najszybciej to zrobisz tak:
generujesz plik TXT za pomocą BCP
bcp z lini poleceń
BCP z poziomu TSQL-a

następnie transportujesz taki plik FTP-em, to można np. zrobić za pomocą FTP.exe, lub czegokolwiek innego
FTP z commandline

następnie robisz z poziomu MySQL-a LOAD INFILE to jakiejś tabeli
LOAD INFILE

jak już coś takiego zrobisz to masz dane w MySQL-u i idzie już szybko

dla przykładu: ładowanie pliku o wielkości 400 MB ~12 mln rekordów to około 30 s

jeżeli zrobisz z tego ładny pliczek CMD i na końcu tego pliku odpalisz kod SQL odpowiedzialny za ładowanie danych to można to zupełnie zautomatyzować
termin
dzięki prachwal właśnie o to mi chodziło. Jestem w szoku szybkością działania tego BCP, 7mln rekordów zapisał do pliku w 35 sekund, plik miał 190MB a po spakowaniu 10MB wiec przez FTP-a poszło bardzo szybko.

Jedna rzecz mnie tylko zastanawia, jak zmienić kodowanie znaków, MS ma CP1250 a MySQL UTF-8.
prachwal
iconv -f CP1250 -t UTF-8 in.txt > out.txt
http://www.filewatcher.com/m/iconv-1.9.2.w...320616.0.0.html
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.