Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Sortowanie duzych tablic
Forum PHP.pl > Forum > PHP
sivyer
Witam,

Mam nastepujacy problem. Musze posortowac dane z pliku CSV wedlug zadanej uprzednio kolumny (zawsze bedzie to liczba). Mozna to latwo i szybko zrobic, jesli linijek w pliku jest nawet do kilkunastu/kilkudziesieciu tysiecy, korzystajac z chocby asort() czy arsort().

W moim przypadku pliki beda mialy srednio po kilkaset tysiecy linijek, a czasem nawet grubo powyzej 1 mln, wiec rozwiazanie oparte o tablice, mimo ze nadal wykonuje sie w akceptowalnym czasie (dla 1mln ok 190sek), to po prostu zabija sprzet.

Przykladowa struktura pliku CSV:

Kod
Kolumna 1;Kolumna 2;Kolumna 3;Kolumna 4;Kolumna 5


I zalozmy ze chce posortowac te dane rosnaco po kolumnie 4. Ma ktos jakis pomysl jak zrobic to optymalnie (moze byc nawet ze strata czasowa, byleby nie pozeralo zbyt wielu zasobow serwera)?

Z gory dziekuje za wszelka pomoc
php programmer
Z czystej ciekawości,
co to są za dane, które przetrzymujsz
w kilkunastu milionach wierszy,

PS. A może zastsować tu metodę dziel i rządź.
jakaś kolumna jest jednoznaczna np wojewodztwo
można by te dane przechowywać nie w jednym ale w kilkunastu plikach,
kązdy plik sortowało by sie osobno w razie zajścia takiej potrzeby

Edit:
Pomysł numer 2: robisz plik indeksu index.cvs
który zawiera kolumne elementu według którego przebiega sortowanie
oraz nazwe pliku gdzie jest reszta danych, sortujescz tylko index.csv
wlq
moze tutaj wstawic sortowanie metoda sladu? dodajesz do bazy danych nowe pole, i przy dodawaniu kolejnych rekordow odpowiednio je zmieniasz, tak, zeby liczby w sladzie odpowiadaly odpowiadaly posortowaniu. Np:

  1. <?php
  2. numer_id | numer_slad
  3. | 3
  4. | 4
  5. | 2 
  6. | 1
  7. ?>


w rezultacie, jak bedzie pobieral dane sladem, bedziesz mial nastepujace numery id: 4, 3, 1, 2
sivyer
Tyle, ze ja otrzymuje jedynie finalne pliki csv, nie mam wplywu na ksztalt bazy w jakiej sa one przechowywane, ani na generowana strukture pliku niestety
wlq
hm...no to chyba jedynym wyjsciem jest sortowanie tablicy. Moze zeby nie marnowac czasu i sprzetu, podziel to na pare mniejszych kawalkow?
tiraeth
Prosty cvs reader potrafi zwrócić Ci coś takiego:
  1. <?php
  2. (
  3.  [0] = Array
  4.  (
  5. [Kolumna 1] = 2,
  6. [Kolumna 2] = 32,
  7. [Kolumna 3] = 415,
  8. [Kolumna 4] = 515,
  9. [Kolumna 5] = 222
  10.  ),
  11.  
  12.  [1] = Array ( )
  13. )
  14. ?>


Tak więc zmieniony przykład z manuala:

  1. <?php
  2. ?php
  3. foreach ($dane as $klucz => $wiersz) {
  4.  $KolumnaOne[$klucz] = $wiersz['Kolumna 1'];
  5.  $KolumnaTwo[$klucz] = $wiersz['Kolumna 2'];
  6.  $KolumnaThree[$klucz] = $wiersz['Kolumna 3'];
  7.  $KolumnaFour[$klucz] = $wiersz['Kolumna 4'];
  8.  $KolumnaFive[$klucz] = $wiersz['Kolumna 5'];
  9. }
  10.  
  11. // Należy podać $dane jako ostatni parametr aby posortować według wspólnego
  12. // klucza
  13. array_multisort($KolumnaFour, SORT_DESC, 
  14. $KolumnaOne, SORT_ASC, 
  15. $KolumnaTwo, SORT_ASC, 
  16. $KolumnaThree, SORT_ASC, 
  17. $KolumnaFive, SORT_ASC, $dane);
  18. ?>


Chyba powinno działać
sivyer
Re: tiraeth

Mam funkcje, ktore dzialaja dokladnie w taki sam sposob, ale zzeraja na jakies 200-300 sekund praktycznie cala dostepna pamiec serwera. Dlatego szukam rozwiazania, ktore moze dzialac nawet wolniej, ale mniej zasobozernie.
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.