Προς το περιεχόμενο

Αναζήτηση, grep ή κάτι άλλο σε τεράστια αρχεία;


capthookb

Προτεινόμενες αναρτήσεις

Έχω 3-4 αρχεία κειμένου τα οποία περιέχουν συνολικά, περίπου 90.000.000 γραμμές με δεδομένα των 4-5 στηλών.
Επίσης έχω μια λίστα από περίπου 7000 νούμερα, τα οποία θέλω να ψάξω μεσα στα 90.000.000 για να πάρω τη γραμμή που αντιστοιχεί σε αυτό το νούμερο.

Ένα απλό grep για κάθε ένα από τα 7000 νούμερα μου αρκεί, με το μόνο μειονέκτημα πως είναι αρκετά αργό. Θέλει κάπου στα 2.5 λεπτά για κάθε νούμερο, δηλαδή θα χρειαστώ κάπου στις 12-13 ημέρες 24ωρης λειτουργιας.
Τι μπορώ να κάνω για να επιταχύνω την αναζήτηση; Εάν περάσω τα 90.000.000 σε μια βάση mysql, θα είναι πιο γρήγορη η αναζήτηση; 
Έχετε κάποια άλλη πρόταση;

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Κοίτα, αν μιλάς για MySQL, με αναζήτηση σε 90.000.000 entries απλά θα πεθάνει από μνήμη.
Αν πάλι μιλάς για Oracle SQL, έχεις μεγαλύτερες πιθανότητες να τα καταφέρεις.

Μια ή άλλη ναι είναι πιο γρήγορο από *SQL αλλά η SQL + οι αναζητήσεις σημαίνει μνήμη.. και μιλάς για αναζήτηση σε 90.000.000 entries όχι 9000.

Παραδειγματικά, στο hoursboost.com έχω κοντά 10.000 πελάτες και δουλεύει σε MySQL. Αν πας να κάνεις fetch array με ολα τα data από το "users", στα πρώτα 10 δευτερόλεπτα θα πεθάνει η MySQL και θα περιμένεις να ξανατρέξει. Σε Dedicated με 16GB Ram αναφέρομαι όχι Gameboy.

Φώτης

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Δημοσ. (επεξεργασμένο)
Αναφορά σε κείμενο

Κοίτα, αν μιλάς για MySQL, με αναζήτηση σε 90.000.000 entries απλά θα πεθάνει από μνήμη.

elaborate please...

@capthookb

Βάλτα σε μία βάση δεδομένων (πχ sqlite), φτιάξε index στη στήλη που θες και η αναζήτηση θα κρατάει ms.

Just for reference, χτες έκανα insert 18M rows σε Postgresql με COPY FROM. Συνολικός χρόνος μαζί με τη δημιουργία indexes κάτω από 10 λεπτο.

edit

βασικά πριν μπλέξεις με βάσεις, δοκίμασε να χρησιμοποιήσεις κάτι ταχύτερο από το grep: https://blog.burntsushi.net/ripgrep/

Επεξ/σία από pmav99
  • Like 1
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Μια χαρά τελικά.

  • Έφτιαξα αρχικά ένα προγραμματάκι σε c, για να μορφοποιήσω τα αρχεία κειμένου σε format csv.
  • Τα τελικά αρχεία csv, τα έσπασα σε αρχεία με 5.000.000 γραμμές το καθένα (split -l 5000000 output.csv). Βγήκαν 19 αρχεία με περίπου 220mb το καθένα.
  • Έφτιαξα τη βάση σε mysql και τον πίνακα με τις στήλες σύμφωνα με το csv. Index στη στήλη με τα νούμερα που θέλω να ψάχνω.
  • Έκανα εισαγωγή τα csv με LOAD DATA

Ο πίνακας έχει συνολικά 91.082.041 γραμμές και 6.7GiB μέγεθος. Η αναζήτηση ενός αριθμού με

>SELECT * FROM people WHERE id=261814

διαρκεί 0.0015 seconds!

  • Like 6
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

  • 4 μήνες μετά...
Δημοσ. (επεξεργασμένο)

Έχω άλλη μια ερώτηση/πρόβλημα που αντιμετωπίζω. Τη βάση την έχω στήσει στο σπίτι μου σε ένα desktop (archlinux) που έχω και χρειάζομαι να τρέχω αναζητήσεις από το φορητό από το γραφείο (internet δηλαδή, έξω από το lan του σπιτιού).

Στο σπίτι έχω ένα raspberry που τρέχει όλο το 24ωρο και στο modem/router του σπιτιού έχω ορίσει port forwarding προς το raspberry για ssh.
Συνεπώς
1)Συνδέομαι με ssh από το φορητό στο raspberry του σπιτιού και με WakeOnLan ανοίγω το desktop μου.
2)Αφού το desktop ξεκινήσει να απαντά σε ping και φορτώσουν όλες οι υπηρεσίες (μαζί με την mysql), κλείνω την ssh σύνδεση και ξανασυνδέομαι από το φορητό στο raspberry, με ssh, μόνο που αυτή τη φορά κάνω και local port forwarding το port της mysql του desktop. Δηλαδή:

#ssh -L 3333:192.168.1.2:3306 user @ raspberry.ddns

όπου 192.168.1.2 είναι η στατική ip του desktop στο lan.
3)Έτσι τώρα μπορώ από το φορητό να συνδεθώ στη mysql του desktop με τα εξής:

mysql -P 3333 -u root -p
	

 

Το πρόβλημα είναι πως τα queries που τρέχω επιστρέφουν μηδενικά αποτελέσματα (empty set).

Ταυτόχρονα τα ίδια ακριβώς queries (copy paste) επιστρέφουν αποτελέσματα, εάν συνδεθώ με ssh στο raspberry και στη συνέχεια με ssh από το raspberry στο desktop και από εκεί με mysql (terminal) τρέξω τις αναζητήσεις μου.

 

Σκέφτεται κάποιος τι μπορεί να φταίει;

 

Το βρήκα τελικά.
Είχα και στο laptop μια βάση πανομοιότυπη η οποία δεν έχει καθόλου δεδομένα. Συνεπώς παρόλο που δήλωνα port 3333 συνδεόμουν στη mysql του localhost του φορητού. Έπρεπε να δηλώσω και --host 127.0.0.1 και όχι localhost, γιατί αλλιώς η σύνδεση γίνεται με socket και δε λαμβάνεται υπόψη το port. Κάτι τέτοιο κατάλαβα τέλοσπάντων.
Η τελική εντολή σύνδεσης είναι:

#mysql --host 127.0.0.1 -P 3333 -u root -p




Έπρεπε να ρυθμίσω και την mysql στο desktop έτσι ώστε να δέχεται συνδέσεις από άλλη ip εντός του Lan, σύμφωνα με το wiki https://wiki.archlinux.org/index.php/MySQL#Grant_remote_access
αλλά τελικά δούλεψε! Επεξ/σία από capthookb
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
  • Δημιουργία νέου...