PDA

View Full Version : [mysql] query LENTISSIME! E' normale?


cipi
19-05-2007, 18:50
Ciao,
sono niubbo di mysql ma devo assolutamente creare e gestire un database che avrà una decina di tabelle ma milioni di dati; una di queste tabelle, infatti, ha circa 40 colonne ma oltre 40 milioni di righe... Ho terminato di importare i primi 8 milioni (da file di testo) di righe; provo a fare qualche query (da notare che ho creato tre PRIMARY KEY e le query erano ristrette a valori su queste colonne) per testarne la velocità e.... :eek: :boh: sono LENTISSIME... (devo attendere ore!)
Ora mi chiedo, avrò sbagliato qualcosa o è normale?
Vi prego, aiuto... sono già molto incacchiato :incazzed:
please!

vizzz
19-05-2007, 19:18
ammazza...sono parecchi record.
non ti è possibile frammentare quella tabella in più sottotabelle? (poi gestisci da codice quale interrogare)
il server è abbastanza performante?
hai provato qualche altro db? (postgres, oracle?)

-fidel-
19-05-2007, 20:48
Ciao,
sono niubbo di mysql ma devo assolutamente creare e gestire un database che avrà una decina di tabelle ma milioni di dati; una di queste tabelle, infatti, ha circa 40 colonne ma oltre 40 milioni di righe... Ho terminato di importare i primi 8 milioni (da file di testo) di righe; provo a fare qualche query (da notare che ho creato tre PRIMARY KEY e le query erano ristrette a valori su queste colonne) per testarne la velocità e.... :eek: :boh: sono LENTISSIME... (devo attendere ore!)
Ora mi chiedo, avrò sbagliato qualcosa o è normale?
Vi prego, aiuto... sono già molto incacchiato :incazzed:
please!

Devi ottimizzare il database, ma non so con mysql quanto spazio di manovra hai. Su Oracle ti saprei aiutare di più. Comunque prova a suddividere la tabella che contiene milioni di record in sottotabelle.
Considera che, se hai una tabella con, mettiamo, 3 milioni di record e dici al database di tirare su la tabella per fare una query, come impostazione di default essa viene caricata in memoria di solito per intero: ovvio che poi ci stai ore per fare una query.
Il problema non è comunque banale.

cionci
20-05-2007, 15:12
Controlla l'uso della memoria e dello swap sul server...se vedi che il server swappa allora monta più memoria...è l'unico modo...
Oppure vale sempre il suggerimento che ti è stato dato: dividi le tabelle...

cipi
20-05-2007, 15:24
ammazza, speravo di aver sbagliato qualcosa...
quindi la via unica sembra quella di spezzare in più tabelle. Ora però i problemi diventano i seguenti:
1) essendo che le tabelle le tiro su da file di testo (giuro, mai visti prima file di testo così grandi... :sofico: ) come LOAD DATA LOCAL INFILE ..., come faccio a dirgli metti le righe da 1 a 100000 in tab1, da 100001 a 200000 in tab2, etc?
2) come gestisco una ricerca di un dato? Se non è in tab1 allora cerca in tab2 e così via o c'è qualche modo pre creare query ad hoc?
PS, grazie hwupgradati... :)

cionci
20-05-2007, 16:01
Hai guardato l'utilizzo della memoria durante la query ?
Che tipo di ricerche devi fare nelle tabelle ? Devi ricercare testo ?

Comunque le tabelle le puoi spezzare dopo che hai importato i dati...

-fidel-
20-05-2007, 16:44
ammazza, speravo di aver sbagliato qualcosa...
quindi la via unica sembra quella di spezzare in più tabelle. Ora però i problemi diventano i seguenti:
1) essendo che le tabelle le tiro su da file di testo (giuro, mai visti prima file di testo così grandi... :sofico: ) come LOAD DATA LOCAL INFILE ..., come faccio a dirgli metti le righe da 1 a 100000 in tab1, da 100001 a 200000 in tab2, etc?
2) come gestisco una ricerca di un dato? Se non è in tab1 allora cerca in tab2 e così via o c'è qualche modo pre creare query ad hoc?
PS, grazie hwupgradati... :)

Non per farmi i fatti tuoi (:)) ma devi necessariamente creare un database per cercare uno o più dati?
Più volte ho avuto a che fare con file con milioni di righe (di solito output di simulazione di traffico di rete, files di testo da 500 Mb), ma per fare le analisi non creavo un database apposta (che diventa la soluzione peggiore...).

cipi
21-05-2007, 09:21
Hai guardato l'utilizzo della memoria durante la query ?
Che tipo di ricerche devi fare nelle tabelle ? Devi ricercare testo ?

Comunque le tabelle le puoi spezzare dopo che hai importato i dati...

La memoria non sembra andare su di molto... (PS: la macchina ha 2 giga di ram) Inoltre si, devo ottenere numeri cercando nel testo. E' un database finanziario, quindi query del tipo:
SELECT fatturato FROM database.dati WHERE country_initials LIKE 'IT'

Interessante la cosa di spezzare dopo le tabelle... mi dici qualcosa in più o dove leggere in merito?

cipi
21-05-2007, 09:25
Non per farmi i fatti tuoi (:)) ma devi necessariamente creare un database per cercare uno o più dati?
Più volte ho avuto a che fare con file con milioni di righe (di solito output di simulazione di traffico di rete, files di testo da 500 Mb), ma per fare le analisi non creavo un database apposta (che diventa la soluzione peggiore...).

In realtà ti stai facendo i fatti miei... :D
Mi serve proprio un database... I dati li devo poi mettere a disposizione via web. Ecco perché le query DEVONO essere veloci!
:help:

cionci
21-05-2007, 09:26
Credevo che tu dovessi fare ricerche in campi di testo molto grandi...in quel caso c'è la possibilità di organizzare la ricerca come full text search.
Comunque in tal caso crea un indice sul campo country_initials e guarda come si comporta.

Riguardo allo spezzare: http://dev.mysql.com/doc/refman/5.0/en/insert-select.html
Seleziona righe con caratteristiche precise dalla tabellona e vai ad inserirle in una tabella più piccola.

simoneart
21-05-2007, 09:26
Il problema potrebbe pure essere nel modo in cui scrivi la query e quindi fai la ricerca sulla tabella.

Per esempio un grosso problema di performance potrebbe essere dato dalla ricerca con LIKE.

Nel caso che hai riportato come esempio conviene probabilmente creare un nuovo campo indicizzato del tipo IT, UK sul quale fare la ricerca diretta dei record che ti interessano.

cipi
21-05-2007, 09:49
Credevo che tu dovessi fare ricerche in campi di testo molto grandi...in quel caso c'è la possibilità di organizzare la ricerca come full text search.
Comunque in tal caso crea un indice sul campo country_initials e guarda come si comporta.

Riguardo allo spezzare: http://dev.mysql.com/doc/refman/5.0/en/insert-select.html
Seleziona righe con caratteristiche precise dalla tabellona e vai ad inserirle in una tabella più piccola.

grazie del link, cionci. Ora gli darò una letta...
Per quanto riguarda country_initials, questo è già indicizzato... La tabella è del tipo:
ID; country_initials; date; data_a; data_b; ...
Io ho indicizzato le prime 3 colonne.
Rimane comunque molto lento... soprattutto se penso che dovrò inserire selle condizioni sui dati tipo "WHERE data_a>0 AND data_b<100"

cipi
21-05-2007, 09:50
Il problema potrebbe pure essere nel modo in cui scrivi la query e quindi fai la ricerca sulla tabella.

Per esempio un grosso problema di performance potrebbe essere dato dalla ricerca con LIKE.

Nel caso che hai riportato come esempio conviene probabilmente creare un nuovo campo indicizzato del tipo IT, UK sul quale fare la ricerca diretta dei record che ti interessano.

Scusa ma sono ancora un po' ignorantello su sql... Intendi dire indicizzare la colonna country_initials o creare qualcos'altro a parte?
thx

thebol
21-05-2007, 10:27
Scusa ma sono ancora un po' ignorantello su sql... Intendi dire indicizzare la colonna country_initials o creare qualcos'altro a parte?
thx

la like rallenta molto le query, cerca di sostituirla con una =

cipi
21-05-2007, 10:28
la like rallenta molto le query, cerca di sostituirla con una =

ok, thx. ;)

kingv
21-05-2007, 20:28
non è che con LIKE usi qualche wildcard?
in questo caso gli indici non verrebbero usati.

cipi
22-05-2007, 09:08
no, nessuna wildcard. Tra l'altro, per la cronaca, ho lanciato due query: una con "valore = 'IT'" e l'altra con "valore LIKE 'IT'" e, sorpresa delle sorprese, ci hanno messo lo stesso tempo.
Comunque il problema non stava li... Ho deciso di studiare bene l'architettura del db; dal mega tabellone di 40e6 righe creerò qualche decina di tabelle da usare a seconda dei casi... Unico modo per ottimizzare, credo.
Attendo altri consigli.
;)

cionci
22-05-2007, 09:10
Probabilmente perché il like senza wildcard viene tradotto con l'uguale...
Guarda anche fra le impostazioni di configurazione di mysql...magari puoi ottimizzare qualcosa anche in quel modo...

kingv
22-05-2007, 10:03
Probabilmente perché il like senza wildcard viene tradotto con l'uguale...



è esatto.
mi sembra strano però che una ricerca indicizzata, anche su una tabella enorme, impieghi minuti.

cionci
22-05-2007, 10:06
Per curiosità: che tipo di tabelle hai creato ? MyISAM o InnoDB ? E' MySQL 5 ?

redcloud
22-05-2007, 10:08
Anche io avevo il tuo stesso problema. Poi ho capito che i DB vanno usati quando sono veramente sfruttati per query complesse, è in questo caso che trai grossi vantaggi. Nel mio caso invece mi serviva solo una tabella con miliardi di righe... mi sono fatto un piccolo DB ad hoc che spezzetta la tebella in più file txt e li comprime/decomprime quando necessario. I tempi di esecuzione migliorano di svariati ordini di grandezza (dopotutto la comunicazione non avviene tramite TCP/IP).

cionci
22-05-2007, 10:08
Leggi questo: http://dev.mysql.com/tech-resources/presentations/presentation-oscon2000-20000719/index.html
Ci sono diverse dritte...

Questa è la parte del amnuale che parla dell'ottimizzazione di cui il link sopra è un sunto: http://dev.mysql.com/doc/refman/5.0/en/optimization.html
http://www.mysqlperformanceblog.com/2006/06/09/why-mysql-could-be-slow-with-large-tables/
http://www.databasejournal.com/features/mysql/article.php/1382791

kingv
22-05-2007, 10:59
sul mio portatile c@gone con un mysql 5.0 e le impostazioni di default su una tabella da 10 milioni di righe la ricerca indicizzata su un campo singolo è istantanea.

non è una questione di ottimizzazione, c'e' qualcosa di macroscopico che rallenta le query

-fidel-
22-05-2007, 11:22
sul mio portatile c@gone con un mysql 5.0 e le impostazioni di default su una tabella da 10 milioni di righe la ricerca indicizzata su un campo singolo è istantanea.

non è una questione di ottimizzazione, c'e' qualcosa di macroscopico che rallenta le query

E se invece fosse il tipo di database che usa? Oppure come crea le tabelle, visto che viene fatto via codice (magari ci sono relazioni tra tabelle che sono eliminabili o che rallentano il tutto).
Per vedere questo, basta che, dopo aver creato il database, fa una query semplice e prendere i tempi di esecuzione.

cipi
22-05-2007, 14:26
è esatto.
mi sembra strano però che una ricerca indicizzata, anche su una tabella enorme, impieghi minuti.

minuti? Su una tabella di 8e6 righe e 80 colonne, una ricerca indicizzata ci ha messo 1h 25 min. :eek:

cipi
22-05-2007, 14:28
Per curiosità: che tipo di tabelle hai creato ? MyISAM o InnoDB ? E' MySQL 5 ?

MySQL ultimissimo e InnoDB...

cipi
22-05-2007, 14:35
E se invece fosse il tipo di database che usa? Oppure come crea le tabelle, visto che viene fatto via codice (magari ci sono relazioni tra tabelle che sono eliminabili o che rallentano il tutto).
Per vedere questo, basta che, dopo aver creato il database, fa una query semplice e prendere i tempi di esecuzione.

Le tabelle sono le più semplici concepibili (credo): semplicemente nate dall'importazione di file di testo...

...
non è una questione di ottimizzazione, c'e' qualcosa di macroscopico che rallenta le query

E' quello che credo anch'io; ma come fare per capirlo?

Leggi questo: http://dev.mysql.com/tech-resources/presentations/presentation-oscon2000-20000719/index.html
Ci sono diverse dritte...

Questa è la parte del amnuale che parla dell'ottimizzazione di cui il link sopra è un sunto: http://dev.mysql.com/doc/refman/5.0/en/optimization.html
http://www.mysqlperformanceblog.com/2006/06/09/why-mysql-could-be-slow-with-large-tables/
http://www.databasejournal.com/features/mysql/article.php/1382791

Grazie cionci, sto leggendo... spero di trovare la soluzione.

cionci
22-05-2007, 14:38
minuti? Su una tabella di 8e6 righe e 80 colonne, una ricerca indicizzata ci ha messo 1h 25 min. :eek:
In effetti c'è qualcosa che non va...io non sono mai arrivato a quelle dimensioni, ma pensa che questo forum si basa tutto su mysql ed ha diversi milioni di post...ed ogni pagina visualizzata di query non ne fa solo una ;)

cipi
22-05-2007, 14:50
In effetti c'è qualcosa che non va...io non sono mai arrivato a quelle dimensioni, ma pensa che questo forum si basa tutto su mysql ed ha diversi milioni di post...ed ogni pagina visualizzata di query non ne fa solo una ;)

:muro: :muro: :muro:


:cry:


ok, appena torno in ufficio provo con EXPLAIN. Vediamo cosa non va. Mi viene un sospetto; qualcuno è così gentile da postare come creerebbe una tabella con le prime 3 colonne come KEY? Forse ho sbagliato qualcosa...
Io non sono in ufficio ma credo di aver scritto qualcosa tipo:
PRIMARY KEY (a), KEY(b), KEY(c)
o no?

kingv
22-05-2007, 17:02
Io non sono in ufficio ma credo di aver scritto qualcosa tipo:
PRIMARY KEY (a), KEY(b), KEY(c)
o no?[/QUOTE]



PRIMARY KEY (a , b, c)

cionci
22-05-2007, 17:11
In teoria KEY da solo sarebbe un alias di INDEX mantenuto per compatibilità...se il tuo scopo era ottenere una chiave primaria su a e due indici su b e c allora va bene...

cipi
22-05-2007, 17:13
Io non sono in ufficio ma credo di aver scritto qualcosa tipo:
PRIMARY KEY (a), KEY(b), KEY(c)
o no?



PRIMARY KEY (a , b, c)

Ok, controllerò... intanto grazie ;)

cipi
22-05-2007, 17:14
In teoria KEY da solo sarebbe un alias di INDEX mantenuto per compatibilità...

ovvero?

cionci
22-05-2007, 17:18
Scusa, ho modificato il post sopra ;)

cipi
23-05-2007, 10:25
Scusa, ho modificato il post sopra ;)

ora è piùchiaro, grazie! ;)

cipi
28-05-2007, 14:10
Ciao,
volevo sapere se qualcuno ha mai creato e operato con indici FULLTEXT. Sapreste dirmi se le query su questi indici sono performanti?
E poi, sapreste spiegarmi il senso di questa frase?
For large datasets, it is much faster to load your data into a table that has no FULLTEXT index and then create the index after that, than to load data into a table that has an existing FULLTEXT index.
tratto da http://dev.mysql.com/doc/refman/5.1/en/fulltext-search.html

thebol
28-05-2007, 14:24
a sentimento l'inserimento di un record in una tabella con tale indice costa x * 10
la creazione di un indice su una tabella con tale indice invece costa x per record

per cui a parità di record contiene prima inserire tutti i record, e poi creare l'indice.

ma a sentimento eh!

cipi
28-05-2007, 20:22
Attenzione a tutti quelli che sono alle prime armi e possono avere il mio problema... ho notevolmente aumentato le prestazioni di select, upload etc. modificando alcuni parametri iniziali.
$ mysqld_safe --key_buffer_size=128M --table_cache=256 \
--sort_buffer_size=4M --read_buffer_size=1M &


Leggete questo articolo molto interessante:
http://213.92.21.88/meo/white/oracle/mys2.htm

cipi
28-05-2007, 20:23
a sentimento l'inserimento di un record in una tabella con tale indice costa x * 10
la creazione di un indice su una tabella con tale indice invece costa x per record

per cui a parità di record contiene prima inserire tutti i record, e poi creare l'indice.

ma a sentimento eh!

ok, allora avevo capito bene... ma la ricerca FULLTEXT com'è? veloce?