Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[database] schema efficiente per avere uno storico dei prezzi

391 views
Skip to first unread message

ga.n

unread,
Jul 5, 2013, 3:22:17 AM7/5/13
to
ho la necessità di importare quotidianamente i listini dei fornitori e
di tenere traccia di eventuali variazioni

ad esempio conoscere in un dato momento gli articoli il cui prezzo è
variato rispetto a sei mesi fa (o rispetto ad una data specifica)
oppure quali sono i prezzi degli ultimi dieci giorni oppure quali erano
i prezzi dalla <data> alla <data>

attualmente (su mysql) viene usata una singola tabella con questa
struttura:

CREATE TABLE `products` (
`file_date` date NOT NULL,
`supplier_id` varchar(128) NOT NULL,
`description` varchar(255) DEFAULT NULL,
`cost` double(10,2) DEFAULT NULL,
PRIMARY KEY (`file_date`,`supplier_id`),
) ENGINE=InnoDB;

i tempi di lettura delle informazioni sono inaccettabili

una query come

SELECT * FROM products AS po WHERE po.supplier_id='CODICE' ORDER BY
file_date DESC LIMIT 0,10;

impiega 12 secondi

fortunatamente questo sistema esisteva già :) e vogliono ampliarlo per
supportare l'importazione da fornitori multipli ma anche per
velocizzare il tutto

ho una macchina linux a disposizione quindi posso passare da mysql a
qualunque altro database engine senza particolari problemi

siccome è la prima volta che mi trovo a dover consultare un archivio di
questo tipo (in cui le date giocano un ruolo fondamentale) sono alla
ricerca di letture consigliate, schemi da cui prendere spunto e
compagnia cantante

grazie anche solo della lettura



--
Ti dirò una cosa Vanessa un proiettile ha lo stesso suono in ogni
lingua, quindi ficcati nel culo una calibro nove!!!


Luca Menegotto

unread,
Jul 5, 2013, 3:50:43 AM7/5/13
to
Il giorno venerdì 5 luglio 2013 09:22:17 UTC+2, ga. n ha scritto:

> ho una macchina linux a disposizione quindi posso passare da mysql a
> qualunque altro database engine senza particolari problemi

Bisognerebbe avere anche un'idea di che quantità di dati stiamo parlando; ecco il motivo per cui devi prendere la mia opinione con le dovute molle.

Io prima di tutto proverei a giocare con gli indici: ne metterei uno per file_date, uno per supplier_id. Tempi così lunghi non sono assolutamente normali.

--
Ciao!
Luca

Soprano

unread,
Jul 5, 2013, 3:54:44 AM7/5/13
to
On Fri, 05 Jul 2013 00:50:43 -0700, Luca Menegotto wrote:

> Il giorno venerdì 5 luglio 2013 09:22:17 UTC+2, ga. n ha scritto:
>
>> ho una macchina linux a disposizione quindi posso passare da mysql a
>> qualunque altro database engine senza particolari problemi
>
> Bisognerebbe avere anche un'idea di che quantità di dati stiamo
> parlando; ecco il motivo per cui devi prendere la mia opinione con le
> dovute molle.

niente endorsment :)

--
Soprano

ga.n

unread,
Jul 5, 2013, 4:49:54 AM7/5/13
to
Stavamo scarsi a Cretinetty, mancava solo Luca Menegotto con l'idea:
> Il giorno venerdì 5 luglio 2013 09:22:17 UTC+2, ga. n ha scritto:

>> ho una macchina linux a disposizione quindi posso passare da mysql a
>> qualunque altro database engine senza particolari problemi

> Bisognerebbe avere anche un'idea di che quantità di dati stiamo parlando;
> ecco il motivo per cui devi prendere la mia opinione con le dovute molle.


esportazione di dieci minuti fa per fare l'import sul database di test

COUNT(*) 14.518.446
COUNT(DISTINCT file_date) 789

quindi ~14M righe e 789 giorni di importazione (con un solo fornitore)

i fornitori diventeranno 4 (forse cinque) per cui la situazione può
solo "peggiorare" :)

facendo una banale divisione l'attuale fornitore ha 18k articoli in
catalogo che vengono importati ogni giorno

ipotizzando che i fornitori diventino 5 e che il numero di articoli sia
più o meno quello avrei 90k righe al giorno in più ovvero 2.7M al mese

magari è sufficiente tenere i dati degli ultimi due anni per cui mi
troverei a gestire come minimo 64.8M di righe

dico come minimo perchè magari i due anni precedente non sono
sufficienti


> Io prima di tutto proverei a giocare con gli indici: ne metterei uno per
> file_date, uno per supplier_id. Tempi così lunghi non sono assolutamente
> normali.

l'alter table è in esecuzione da venti minuti :)

provo e ti faccio sapere

per il momento grazie

--
vuoi mettere l'emozione di dormire davanti alla saracinseca abbassata
di mediaworld insieme ad altri disadattati, dopo una cena frugale
davanti al fuoco?
anzi no, il fuoco non si può accendere
facciamo che ceniamo a merendine


Soprano

unread,
Jul 5, 2013, 4:46:21 AM7/5/13
to
On Fri, 05 Jul 2013 09:22:17 +0200, ga.n wrote:

> grazie anche solo della lettura

pre

--
Soprano

ga.n

unread,
Jul 5, 2013, 5:00:41 AM7/5/13
to
Soprano ci ha detto :
> On Fri, 05 Jul 2013 09:22:17 +0200, ga.n wrote:

>> grazie anche solo della lettura

> pre

ma quanto sei sciocchino? quanto?

--
la differenza è che lei me la chiaverei e da cieca non è detto che non
ci stia


Luca Menegotto

unread,
Jul 5, 2013, 5:05:58 AM7/5/13
to
Il giorno venerdì 5 luglio 2013 10:49:54 UTC+2, ga. n ha scritto:

> COUNT(*) 14.518.446

Una discreta quantità, non una roba drammatica. MySQL, per quel che lo conosco e per quel che me ne raccontano, dovrebbe gestirli con una certa tranquillità (anzi, dovrebbe essere il suo punto di forza).


> facendo una banale divisione l'attuale fornitore ha 18k articoli in
> catalogo che vengono importati ogni giorno

Il che significa che importa tutti i dati tutti i giorni, che siano variati o che non lo siano.... questo è male, duplicazioni inutili.

> l'alter table è in esecuzione da venti minuti :)
>
> provo e ti faccio sapere

Aggiungo uno spunto generale che magari può servire. Dai un occhio anche a quante risorse sono allocate a quel dbms in termini di RAM e processore.

--
Ciao!
Luca

rootkit

unread,
Jul 5, 2013, 5:26:08 AM7/5/13
to
Il Fri, 05 Jul 2013 09:22:17 +0200, ga.n ha scritto:

> ho la necessità di importare quotidianamente i listini dei fornitori e
> di tenere traccia di eventuali variazioni
>
> ad esempio conoscere in un dato momento gli articoli il cui prezzo è
> variato rispetto a sei mesi fa (o rispetto ad una data specifica) oppure
> quali sono i prezzi degli ultimi dieci giorni oppure quali erano i
> prezzi dalla <data> alla <data>

l'inefficienza secondo me è dovuta al fatto che l'indice della pk è
invertito rispetto alla selettività che ti serve, o cambi l'ordine di
file_date, supplier_id oppure crei un altro indice.

per il resto la query corretta è qualcosa del tipo (da provare,
ovviamente):

WHERE po.supplier_id='CODICE'
and po.file_date = (select max(po1.file_date)
from products po1
where po1.supplier_id = po.supplier_id
and po1.file_date <= <data> )

dove <data> è la data di cui vuoi sapere il prezzo attivo.

ga.n

unread,
Jul 5, 2013, 5:45:42 AM7/5/13
to
Dopo dura riflessione, Luca Menegotto ha scritto :
> Il giorno venerdì 5 luglio 2013 10:49:54 UTC+2, ga. n ha scritto:

>> COUNT(*) 14.518.446

> Una discreta quantità, non una roba drammatica. MySQL, per quel che lo
> conosco e per quel che me ne raccontano, dovrebbe gestirli con una certa
> tranquillità (anzi, dovrebbe essere il suo punto di forza).

>> facendo una banale divisione l'attuale fornitore ha 18k articoli in
>> catalogo che vengono importati ogni giorno

> Il che significa che importa tutti i dati tutti i giorni, che siano variati o
> che non lo siano.... questo è male, duplicazioni inutili.

si ma lo trovo comprensibile perchè una delle query che vogliono
eseguire è:

trova i prodotti il cui prezzo è cambiato confrontando il 03-07-2013 e
il 20-09-2012

come fai se non memorizzi il prezzo di ogni giorno?


>> l'alter table è in esecuzione da venti minuti :)
>>
>> provo e ti faccio sapere

> Aggiungo uno spunto generale che magari può servire. Dai un occhio anche a
> quante risorse sono allocate a quel dbms in termini di RAM e processore.

questo lo posso verificare ma non credo siano disposti a cambiare
hardware

--
non sono ricchione, e mi sa che non sono più comunista


ispas

unread,
Jul 5, 2013, 5:53:55 AM7/5/13
to
Il giorno venerdì 5 luglio 2013 09:22:17 UTC+2, ga. n ha scritto:
> ho la necessità di importare quotidianamente i listini dei fornitori e
>
> di tenere traccia di eventuali variazioni
>
>
>
> ad esempio conoscere in un dato momento gli articoli il cui prezzo è
>
> variato rispetto a sei mesi fa (o rispetto ad una data specifica)
>
> oppure quali sono i prezzi degli ultimi dieci giorni oppure quali erano
>
> i prezzi dalla <data> alla <data>
>
>
>
> attualmente (su mysql) viene usata una singola tabella con questa
>
> struttura:
>
>
>
> CREATE TABLE `products` (
>
> `file_date` date NOT NULL,
>
> `supplier_id` varchar(128) NOT NULL,
>
> `description` varchar(255) DEFAULT NULL,
>
> `cost` double(10,2) DEFAULT NULL,
>
> PRIMARY KEY (`file_date`,`supplier_id`),
>
> ) ENGINE=InnoDB;
>
>
>
> i tempi di lettura delle informazioni sono inaccettabili
>
>
>
> una query come
>
>
>
> SELECT * FROM products AS po WHERE po.supplier_id='CODICE' ORDER BY
>
> file_date DESC LIMIT 0,10;
>
>
>
> impiega 12 secondi
>
>
>
> fortunatamente questo sistema esisteva già :) e vogliono ampliarlo per
>
> supportare l'importazione da fornitori multipli ma anche per
>
> velocizzare il tutto

L'indice sembra fatto in maniera tale che una richiesta per un dato codice supplier, senza indicare una data, implica una scansione sequenziale della tabella. Servirebbe un indice secondario sul solo codice supplier.



> ho una macchina linux a disposizione quindi posso passare da mysql a
>
> qualunque altro database engine senza particolari problemi


Pure Oracle, DB2, Sql Server?

rootkit

unread,
Jul 5, 2013, 5:55:50 AM7/5/13
to
Il Fri, 05 Jul 2013 11:45:42 +0200, ga.n ha scritto:


> si ma lo trovo comprensibile perchè una delle query che vogliono
> eseguire è:
>
> trova i prodotti il cui prezzo è cambiato confrontando il 03-07-2013 e
> il 20-09-2012
>
> come fai se non memorizzi il prezzo di ogni giorno?

trovi tutti i prodotti la cui max(file_date) per quel prodotto <=
03-07-2013 è uguale a quella <= 20-09-2012.

Luca Menegotto

unread,
Jul 5, 2013, 6:00:07 AM7/5/13
to
Il giorno venerdì 5 luglio 2013 11:45:42 UTC+2, ga. n ha scritto:

> come fai se non memorizzi il prezzo di ogni giorno?

Due tabelle, una che memorizza gli articoli, una che memorizza le variazioni giornaliere.

Il resto è solo una questione di query opportune.

> questo lo posso verificare ma non credo siano disposti a cambiare
> hardware

OCIO! Potrebbe anche non essere una questione hardware. Non so MySql, ma sicuramente SQL Server e - quasi - sicuramente PostgreSQL hanno la possibilità di indicare sia la quantità massima di RAM e il numero massimo di processori da impiegare.

--
Ciao!
Luca

Stefano Zamboni

unread,
Jul 5, 2013, 6:04:02 AM7/5/13
to
Il Fri, 05 Jul 2013 09:26:08 +0000, rootkit ha scritto:

> per il resto la query corretta è qualcosa del tipo (da provare,
> ovviamente):
>
> WHERE po.supplier_id='CODICE'
> and po.file_date = (select max(po1.file_date)
> from products po1 where po1.supplier_id = po.supplier_id and
> po1.file_date <= <data> )
>
> dove <data> è la data di cui vuoi sapere il prezzo attivo.

a parte i discorsi su pk e indici, la mia esperienza mi dice che mysql si
siede paurosamente in caso di subquery del genere..

meglio una SP dove eseguo le due query separate e passo la data alla
seconda query

all IMVHO

S.

rootkit

unread,
Jul 5, 2013, 6:26:42 AM7/5/13
to
Il Fri, 05 Jul 2013 10:04:02 +0000, Stefano Zamboni ha scritto:


>> WHERE po.supplier_id='CODICE'
>> and po.file_date = (select max(po1.file_date)
>> from products po1 where po1.supplier_id = po.supplier_id and
>> po1.file_date <= <data> )
>>
>> dove <data> è la data di cui vuoi sapere il prezzo attivo.
>
> a parte i discorsi su pk e indici, la mia esperienza mi dice che mysql
> si siede paurosamente in caso di subquery del genere..

bah io ho avuto un problema simile usando h2 (un db scrio scrio pure java
che gira anche in embedded mode) su diversi milioni di righe e se la cava
almeno decentemente... penso che se ci sono gli indici giusti non c'è
motivo di sedersi, è vero che esegue molte volte la subqery che però
dovrebbe essere istantanea visto che rimane sempre sull'indice.

ga.n

unread,
Jul 5, 2013, 6:31:10 AM7/5/13
to
ispas scriveva il 05/07/2013 :
hai centrato il problema :)

pensavo (erroneamente a quanto pare) che la pk fosse sufficiente

faccio alcuni test più approfonditi ma i tempi sono decisamente
migliorati

creando un indice su supplier_id la stessa query, dopo un riavvio del
servizio e cambiando il codice prodotto, impiega 2 secondi che sono
ancora tanti

mi sa che è meglio approfondire le mie conoscenze in fatto di indici

>> ho una macchina linux a disposizione quindi posso passare da mysql a
>>
>> qualunque altro database engine senza particolari problemi

> Pure Oracle, DB2, Sql Server?

nelle due righe di sopra c'era un "open source" non scritto :-)



--
zeitgeist ha uno uno stile pseudo-documentarista che va tanto di moda:
ti copre di illazioni e sentito dire, mischia il vero col possibile e
col falso in un unico calderone e alla fine ti porta alle conclusioni
che vuole l'autore, cosa che va tanto di moda tra i giovini ritardati
che si credono di sinistra di oggi.


ga.n

unread,
Jul 5, 2013, 6:38:59 AM7/5/13
to
rootkit ha usato la sua tastiera per scrivere :
> Il Fri, 05 Jul 2013 09:22:17 +0200, ga.n ha scritto:

>> ho la necessità di importare quotidianamente i listini dei fornitori e
>> di tenere traccia di eventuali variazioni
>>
>> ad esempio conoscere in un dato momento gli articoli il cui prezzo è
>> variato rispetto a sei mesi fa (o rispetto ad una data specifica) oppure
>> quali sono i prezzi degli ultimi dieci giorni oppure quali erano i
>> prezzi dalla <data> alla <data>

> l'inefficienza secondo me è dovuta al fatto che l'indice della pk è
> invertito rispetto alla selettività che ti serve, o cambi l'ordine di
> file_date, supplier_id oppure crei un altro indice.

effettivamente creando un indice su supplier_id la situazione è
migliorata

approfondisco il discorso indici

> per il resto la query corretta è qualcosa del tipo (da provare,
> ovviamente):

> WHERE po.supplier_id='CODICE'
> and po.file_date = (select max(po1.file_date)
> from products po1
> where po1.supplier_id = po.supplier_id
> and po1.file_date <= <data> )

> dove <data> è la data di cui vuoi sapere il prezzo attivo.

il prezzo di un singolo giorno non viene richiesto praticamente mai

come query di riferimento ho

- i prezzi in un determinato intervallo temporale (gli ultimi dieci
giorni, dal 20-09-2012 al 10-10-2012)
- i prezzi che sono variati confrontando due date specifiche

in ogni caso sono ancora in fase di analisi ed ho tempi abbastanza
ragionevoli per cui preferisco analizzare con calma la situazione e
approfittando per approfondire le mie conoscenze in materia.





--
Che dire di a||&v| che non sia gia' stato detto della dissenteria?


ispas

unread,
Jul 5, 2013, 7:02:56 AM7/5/13
to
Il giorno venerdì 5 luglio 2013 12:31:10 UTC+2, ga. n ha scritto:
> creando un indice su supplier_id la stessa query, dopo un riavvio del
>
> servizio e cambiando il codice prodotto, impiega 2 secondi che sono
>
> ancora tanti


Dipende anche da quante righe tira fuori per singolo supplier, se ho capito bene siamo nei paraggi di qualche milione di righe. Come verifichi i tempi? Vedi quanto ci mette a rispondere il tool con cui fare la query?

s1gfr1...@libero.it

unread,
Jul 5, 2013, 7:36:24 AM7/5/13
to
On 05/07/2013 09:22, ga.n wrote:
> ho la necessità di importare quotidianamente i listini dei fornitori e
> di tenere traccia di eventuali variazioni
>
> ad esempio conoscere in un dato momento gli articoli il cui prezzo è
> variato rispetto a sei mesi fa (o rispetto ad una data specifica)
> oppure quali sono i prezzi degli ultimi dieci giorni oppure quali erano
> i prezzi dalla <data> alla <data>
>
> attualmente (su mysql) viene usata una singola tabella con questa
> struttura:
>
> CREATE TABLE `products` (
> `file_date` date NOT NULL,
> `supplier_id` varchar(128) NOT NULL,
> `description` varchar(255) DEFAULT NULL,
> `cost` double(10,2) DEFAULT NULL,
> PRIMARY KEY (`file_date`,`supplier_id`),
> ) ENGINE=InnoDB;
>
> i tempi di lettura delle informazioni sono inaccettabili
>
> una query come
>
> SELECT * FROM products AS po WHERE po.supplier_id='CODICE' ORDER BY
> file_date DESC LIMIT 0,10;
>

>
>
Hai provato ad utilizzare l'istruzione EXPLAIN per analizzare la query
e trovare i possibili colli di bottiglia?

Andrea Venturoli

unread,
Jul 5, 2013, 9:39:20 AM7/5/13
to
On 07/05/13 09:22, ga.n wrote:
> ho la necessità di importare quotidianamente i listini dei fornitori e
> di tenere traccia di eventuali variazioni
>
> ad esempio conoscere in un dato momento gli articoli il cui prezzo è
> variato rispetto a sei mesi fa (o rispetto ad una data specifica)
> oppure quali sono i prezzi degli ultimi dieci giorni oppure quali erano
> i prezzi dalla <data> alla <data>
>
> attualmente (su mysql) viene usata una singola tabella con questa
> struttura:
>
> CREATE TABLE `products` (
> `file_date` date NOT NULL,
> `supplier_id` varchar(128) NOT NULL,
> `description` varchar(255) DEFAULT NULL,
> `cost` double(10,2) DEFAULT NULL,
> PRIMARY KEY (`file_date`,`supplier_id`),
> ) ENGINE=InnoDB;

Sono l'unico che sposterebbe supplier_id e description in un'altra
tabella collegata?
E' una cretinata?

bye
av.

enoquick

unread,
Jul 5, 2013, 9:48:18 AM7/5/13
to
No, lo farei anch'io
Duplicare la descrizione non è una bella cosa a meno che non possa
cambiare per una nuova entry (cosa che non credo)


ga.n

unread,
Jul 5, 2013, 10:45:43 AM7/5/13
to
Dopo dura riflessione, ispas ha scritto :
> Il giorno venerdì 5 luglio 2013 12:31:10 UTC+2, ga. n ha scritto:
>> creando un indice su supplier_id la stessa query, dopo un riavvio del
>>
>> servizio e cambiando il codice prodotto, impiega 2 secondi che sono
>>
>> ancora tanti

> Dipende anche da quante righe tira fuori per singolo supplier,

questa informazioni la vedo con EXPLAIN giusto?

ad esempio in questo caso

http://pastebin.com/SFrRR1jy

sono 330?

> se ho capito
> bene siamo nei paraggi di qualche milione di righe.

sul database di test sono ~14 milioni ma verosimilmente cresceranno al
ritmo di 90 mila al giorno

> Come verifichi i tempi?
> Vedi quanto ci mette a rispondere il tool con cui fare la query?

sì, nello specifico il client a linea di comando di mysql lanciato
sulla stessa macchina

è un metodo sbagliato? è poco significativo?

--
Lo stimo attratti e abbestia, solo che quando prende gli acidi scaduti,
proprio non si sopporta.


Luca Menegotto

unread,
Jul 5, 2013, 11:20:35 AM7/5/13
to
Il giorno venerdì 5 luglio 2013 15:39:20 UTC+2, Andrea Venturoli ha scritto:

> Sono l'unico che sposterebbe supplier_id e description in un'altra
> tabella collegata?
> E' una cretinata?

Più che altro non ne vedo il motivo, che ci sono gli indici che sostanzialmente fanno la stessa cosa e non ti devi occupare tu della loro manutenzione.

--
Ciao!
Luca

ispas

unread,
Jul 5, 2013, 12:54:57 PM7/5/13
to
Il giorno venerdì 5 luglio 2013 16:45:43 UTC+2, ga. n ha scritto:
> > Dipende anche da quante righe tira fuori per singolo supplier,
>
>
>
> questa informazioni la vedo con EXPLAIN giusto?
>
>
>
> ad esempio in questo caso
>
>
>
> http://pastebin.com/SFrRR1jy
>
>
>
> sono 330?

Direi di sì. Ma è giusto che su 14 milioni un generico supplier abbia solo 330 righe? Mi sembra comunque un punto di attenzione anche la chiave lunga ben 130 caratteri, laddove nel tuo esempio ne usi solo una quindicina.

> > Vedi quanto ci mette a rispondere il tool con cui fare la query?
>
>
>
> sì, nello specifico il client a linea di comando di mysql lanciato
>
> sulla stessa macchina
>
>
>
> è un metodo sbagliato? è poco significativo?

Se ti basi sulla risposta del client, devi tener conto che un certo tempo viene impiegato per formattare a video (od in stampa, od altro) i risultati. Quindi un tempo più o meno lungo potrebbe dipendere anche dalla maggiore o minore efficienza del tool client nel fare tale formattazione.
Per esempio io uso con Oracle un programma che di default limita le righe ritornate a 100, così da avere una risposta il più possibile rapida. Poi se scorri a video la tabella risultato ovviamente vedi il tempo reale dell'intera select.
Certo nel tuo caso 2 secondi per tornare 330 righe con un indice dedicato ed appena creato, usando il client originale Mysql, non mi sembrano realmente una gran prestazione.
Il passo successivo potrebbe essere verificare la situazione fisica del db (tabelle più o meno disorganizzate, spazi disponibili, RAM usata, ecc.), e eventualmente il carico di rete (se stai provando da un pc diverso dal server).
Ma qui passo la palla a qualcuno esperto di Mysql dal punto sistemistico :-)

ispas

unread,
Jul 5, 2013, 1:04:10 PM7/5/13
to
Il giorno venerdì 5 luglio 2013 15:39:20 UTC+2, Andrea Venturoli ha scritto:
All'incirca, dovresti quindi sostituire products.description con products.desc_id, con la seconda tabella di "decodifica" tra l'id e la descrizione.
Per evitare duplicazioni, dovresti inoltre creare un processo di scrittura che prima quarda se esiste una descrizione esattamente uguale, in tal caso ne riusa l'id, altrimenti inserisce una nuova riga descrizione con un nuovo id (trigger di inserimento ed aggiornamento su products? logica applicativa?).
Mi sembra piuttosto complicato, per risparmiare pochi GB. E su un sistema che fatica già a tirare fuori 330 righe indicizzate.

fm

unread,
Jul 5, 2013, 1:35:06 PM7/5/13
to
CUT
>Mi sembra piuttosto complicato, per risparmiare pochi GB. E su un sistema
>che fatica già a tirare fuori 330 righe indicizzate.


poi si scopri' che il "server" era un Pentium IV con attaccato un disco usb
da 4 Tera....:-)

ciao
fm


Daniele Orlandi

unread,
Jul 5, 2013, 2:36:34 PM7/5/13
to
Io in questo schema ci vedo un sacco di problemi, non solo quello, provo
velocemente a elencarli:

- Le chiavi private devono essere opache e compatte
- Manca una chiave esterna e univoca per il prodotto
- Gli ID per collegare i record devono essere compatti e opachi
- Bisogna separare i dati stabili da quelli storici
- È essenziale mettere gli indici giusti, il che include anche l'uso degli
indici composti!
- Per la cronaca, un buon DBMS usa l'indice per un ORDER BY + LIMIT
- È essenziale usare EXPLAIN per verificare che il query plan sia quello
atteso
- Non si usano i floating point per memorizzare prezzi
- Si usano veri DBMS :)

Poi si entra nel campo delle opinioni:

- Io terrei il prezzo corrente nel record del prodotto così l'accesso è
immediato.
- Creerei un'altra tabella con la storia dei prezzi, collegata a questa via
product_id che contiene la data fino cui era valido e il prezzo.
- Ogni volta che un prodotto riceve un aggiornamento di prezzo si inserisce
il nuovo prezzo nel record "product" e si inserisce nello storico il vecchio
prezzo con la data odierna.

Ottenere uno storico è banale e rapido visto che è un index scan di piccole
dimensioni.

Così facendo ridurresti drasticamente le dimensioni del database in termini
di numero di record e spazio.

14 milioni di record non sono nulla di folle e un index scan di 10 record
deve impiegare nell'ordine di grandezza del millisecondo, non dei 10 secondi
:)

rootkit

unread,
Jul 5, 2013, 4:12:11 PM7/5/13
to
onestamente se quello è il problema e quelli sono i numeri sono
abbastanza certo che si possa fare anche con un raspberry. posso capire
se ci si ponesse il problema di numerosi accessi simultanei ma se siamo
ancora a parlare di una query su una tabella non mi pare serva chissà che
potenza di calcolo.

ispas

unread,
Jul 5, 2013, 4:39:28 PM7/5/13
to
Il giorno venerdì 5 luglio 2013 20:36:34 UTC+2, Daniele Orlandi ha scritto:
> - Manca una chiave esterna e univoca per il prodotto

Ragionandoci, in realtà manca la chiave del fornitore! Supplier_id non è quella chiave lì, come pensavo inizialmente, bensì sembra essere la chiave del prodotto entro il fornitore. Essendo lunga 128 caratteri, probabilmente è una chiave composta da codice fornitore+ codice prodotto, tutto dentro un'unica stringona-secchione...

fm

unread,
Jul 6, 2013, 1:17:43 AM7/6/13
to

"ispas" <gid...@interfree.it> ha scritto nel messaggio
news:3eddeae6-01f0-4e79...@googlegroups.com...
... dog's penis style ...

90 mega 90 giga in piu' al giorno....che differenza fa?

Arrivera' sicuramente qualcuno a dire che si risolve tutto con il cloud
!...:-)


ciao
fm





ga.n

unread,
Jul 6, 2013, 2:08:29 AM7/6/13
to
Nel suo scritto precedente, ispas ha sostenuto :
> Il giorno venerdì 5 luglio 2013 20:36:34 UTC+2, Daniele Orlandi ha scritto:
>> - Manca una chiave esterna e univoca per il prodotto

> Ragionandoci, in realtà manca la chiave del fornitore! Supplier_id non è
> quella chiave lì, come pensavo inizialmente, bensì sembra essere la chiave
> del prodotto entro il fornitore.

esatto è il codice prodotto del fornitore

> Essendo lunga 128 caratteri, probabilmente è
> una chiave composta da codice fornitore+ codice prodotto, tutto dentro
> un'unica stringona-secchione...

no. è solamente il codice prodotto

in quel database (che poi è tutto in quella tabella) non ci sono
informazioni sui fornitori in quanto il sistema attuale gestisce un
unico fornitore. chi ha creato questo sistema non si è neanche posto il
problema

--
alla bambina di un anno non gliene frega un cazzo di quel che fate
la festa è solo per la vostra vanagloria di neogenitori quindi fai pure
la solita torta all'hascish e alla bimba metti un pò di nesquik nel
latte per festeggiare


fm

unread,
Jul 6, 2013, 2:20:09 AM7/6/13
to

"rootkit" <roo...@email.it> ha scritto nel messaggio
news:kr79ap$6co$1...@speranza.aioe.org...
una tabella da 70 milioni di righe lunghe circa 400 bytes sono
oltre 28 GB su disco...(?)

Entrano anche su un disco EIDE/ATA di 15 anni fa.....
proviamo e poi vediamo le prestazioni....


ciao
fm


fm

unread,
Jul 6, 2013, 4:31:04 AM7/6/13
to

CUT
>
> esatto è il codice prodotto del fornitore
>
>> Essendo lunga 128 caratteri, probabilmente è una chiave composta da
>> codice fornitore+ codice prodotto, tutto dentro un'unica
>> stringona-secchione...
>
> no. è solamente il codice prodotto
>
non sappiamo di quale categoria merceologica stiamo parlando,
ma un codice prodotto di 128 caratteri mi sembra comunque una stronzata ...

Ce l'ho a morte con le codifiche idiote, es quella di infilare
nei codici prodotto i caratteri speciali ".", "/", "+" , "#" e compagnia
cantante...

> in quel database (che poi è tutto in quella tabella) non ci sono
> informazioni sui fornitori in quanto il sistema attuale gestisce un unico
> fornitore. chi ha creato questo sistema non si è neanche posto il problema
>
Si, voleva fare alla svelta: "Prendi i soldi e scappa".

... puoi aggiungere la colonna codice fornitore,
se ne hai al max 5, mi raccomando che sia di 1 (uno) carattere...:-)

ciao
fm


ispas

unread,
Jul 6, 2013, 9:16:14 AM7/6/13
to
Il giorno sabato 6 luglio 2013 08:08:29 UTC+2, ga. n ha scritto:
> esatto è il codice prodotto del fornitore


Ok, questo mi chiarisce come mai per un codice trova 330 righe soltanto, equivocavo con il fornitore.

> in quel database (che poi è tutto in quella tabella) non ci sono
>
> informazioni sui fornitori in quanto il sistema attuale gestisce un
>
> unico fornitore. chi ha creato questo sistema non si è neanche posto il
>
> problema

Come ho detto, mi sembra un pò troppo lunga, potrebbe inficiare le prestazioni. In ogni caso se ci sono codici che usano tutti i 128 caratteri non ci si può fare molto.
Verifica lo stato fisico della tabella, a causa dei 90.000 inserimenti giornalieri (magari in corso da anni) potrebbe essere troppo frammentata. Se in Mysql non c'è un comando apposito di riorganizzazione, non resta che un bel backup e successivo restore.

rootkit

unread,
Jul 6, 2013, 10:53:22 AM7/6/13
to
Il Sat, 06 Jul 2013 08:20:09 +0200, fm ha scritto:


>>> poi si scopri' che il "server" era un Pentium IV con attaccato un
>>> disco usb da 4 Tera....:-)
>>
>> onestamente se quello è il problema e quelli sono i numeri sono
>> abbastanza certo che si possa fare anche con un raspberry. posso capire
>> se ci si ponesse il problema di numerosi accessi simultanei ma se siamo
>> ancora a parlare di una query su una tabella non mi pare serva chissà
>> che potenza di calcolo.
>
> una tabella da 70 milioni di righe lunghe circa 400 bytes sono oltre 28
> GB su disco...(?)

> Entrano anche su un disco EIDE/ATA di 15 anni fa..... proviamo e poi
> vediamo le prestazioni....

certo se gli dai un server e dei dischi di ultima generazione peggio non
va, come direbbe il fù catalano. quello che sto dicendo è che una
operazione del genere in se non ha bisogno ne di potenza di calcolo e ne
di chissà quali transfer rate del disco. che siano 28 giga di dati non
glie ne può fregare di meno, io ho una libreria multimediale di un paio
di tera gestita da un raspberry pi che fa il suo lavoro in maniera
eccellente. certo che se uno i dati li struttura a capocchia o inserisce
badilate di righe inutili è possibile che poi per ricercarli servano otto
core, però qualsiasi programma di magazzino per fare la valorizzazione
deve andare a leggere i listini ad una data e non mi pare che girino
tutti su server di ultima generazione...

vittorio

unread,
Jul 6, 2013, 6:38:53 PM7/6/13
to
> trovi tutti i prodotti la cui max(file_date) per quel prodotto <=
> 03-07-2013 č uguale a quella <= 20-09-2012.

cioč? Non si capisce.


rootkit

unread,
Jul 7, 2013, 6:15:38 AM7/7/13
to
Il Sun, 07 Jul 2013 00:38:53 +0200, vittorio ha scritto:

>> trovi tutti i prodotti la cui max(file_date) per quel prodotto <=
>> 03-07-2013 è uguale a quella <= 20-09-2012.
>
> cioè? Non si capisce.

se registri (come è logico fare) solo le variazioni di listino di un
prodotto puoi cercare l'ultima variazione alle due date, se corrispondono
allora ovviamente vuol dire che fra le due date non ci sono state
variazioni.

kojak

unread,
Jul 7, 2013, 6:41:50 AM7/7/13
to
Il giorno venerdì 5 luglio 2013 12:00:07 UTC+2, Luca Menegotto ha scritto:
> Il giorno venerdì 5 luglio 2013 11:45:42 UTC+2, ga. n ha scritto:
>
>
> > come fai se non memorizzi il prezzo di ogni giorno?
>
>
> Due tabelle, una che memorizza gli articoli, una che memorizza
> le variazioni giornaliere.
>


da un punto di vista puramente logico anche a me sembra più
corretto così. Anziché memorizzare tutte le informazioni su
un'unica tabella, si fa una tabella Product con id e
description, e si fa una tabella Product_Cost con id_product,
date e cost.
In fondo si tratta di due entità diverse, il prodotto e il
costo, legate dall'id del prodotto.
Tanto poi se c'è necessità di estrarre tutte le informazioni
basta una semplice join.


Però non saprei assolutamente dire se così i tempi di lettura
si riducono: io l'ho pensata da una prospettiva puramente
logica.
Per quello che posso dire io, le query su tabelle con qualche
migliaio o decine di migliaia di dati non sono istantanee,
impiegano sempre un po' di secondi.
Qui si parla invece di milioni di dati...



>
>
> Il resto è solo una questione di query opportune.
>

ah, questo vale sempre, non c'è che dire.



P.S.
io come db conbosco mysql, oracle e sql server, e dei tre il
paggiore mi sembra proprio mysql.
Non può essere che con sql server o oracle, pur restando il
discorso delle due tabelle, la situazione potrebbe migliorare?

fm

unread,
Jul 7, 2013, 7:06:42 AM7/7/13
to

CUT
>
> certo se gli dai un server e dei dischi di ultima generazione peggio non
> va,come direbbe il fù catalano.

non e' che peggio non va....va meglio anzi MOLTO MEGLIO.

A riprova ho fatto un mini-test su di un "serverino" di due-tre anni fa
( allora non molto costoso ed oggi praticamente alla portata di tutti,
l'hw x86 praticamente te lo dirano dietro).

I risultati in termini di prestazioni, rispetto a quelli riportati dall'OP,
sono IMPIETOSI.
il tempo della query e' di un ordine di grandezza inferiore (diciamo 20
volte inferiore).
0,1 secondi per estrarre 1200 righe da una tabella con 15 milioni di righe
(presentandone 10)...
tempo cpu 31 msec.

-----------------------------------------------------------------------------
Conteggio righe tabella 15.323.728

Dimensione righe 198 Byte

Campo descrizione lunghezza 70 Byte





SET STATISTICS TIME ON

GO

SELECT TOP 10 *

FROM [test].[dbo].[articoli]

WHERE descrizione = 'xyx' ORDER BY data_ultimo_aggiornamento DESC

GO

SET STATISTICS TIME OFF

GO



Risultato della query a video: istantaneo




Messaggi:



Tempo di analisi e compilazione SQL Server:

tempo di CPU = 0 ms, tempo trascorso = 0 ms.



(Righe interessate: 10)



(Righe interessate: 1)



Tempo di esecuzione SQL Server:

tempo di CPU = 31 ms, tempo trascorso = 101 ms.

Tempo di analisi e compilazione SQL Server:

tempo di CPU = 0 ms, tempo trascorso = 0 ms.



Dal piano di esecuzione:

numero stimato righe 1232

-----------------------------------------------------------------------------
la macchina :
IBM System x3650 M3,
2 cpu x Intel Xeon X5650 @ 2.67GHz (6 core)
16 GB DDR3
4 Hd 150Gb 15K SAS in raid 5
-----------------------------------------------------------------------------

> quello che sto dicendo è che una
> operazione del genere in se non ha bisogno ne di potenza di calcolo e ne
> di chissà quali transfer rate del disco. che siano 28 giga di dati non
> glie ne può fregare di meno, io ho una libreria multimediale di un paio
> di tera gestita da un raspberry pi che fa il suo lavoro in maniera
> eccellente.

ci credo ma e' un caso diverso .... si tratta di centinaia o migliaia di
oggetti
di grandi dimensioni.
Quella dell'OP e' una tabella di decine di milioni di righe da circa 400 (?)
byte

>certo che se uno i dati li struttura a capocchia o inserisce
> badilate di righe inutili è possibile che poi per ricercarli servano otto
> core,
Ovviamente: merd-in merd out ...
L'errore fondamentale e' stato quello di inserire bovinamente tutte le righe
giornalmente
ricevute dal fornitore, anziche' le VARIAZIONI di prezzo.
In quest'ultima maniera le righe sarebbero state 100-200K anzichè 14M in due
anni.
Quante variazioni di prezzo puo fare, in due anni, un fornitore che ha 18K
referenze ?

>però qualsiasi programma di magazzino per fare la valorizzazione
> deve andare a leggere i listini ad una data e non mi pare che girino
> tutti su server di ultima generazione...
>
c'entra poco o nulla.
In genere quando si fa una valorizzazione di magazzino non si sta col
cronomentro
in mano a misurare i tempi (vale per il sw della Finson a 29.90 euro e per
il SAP)

Invece l'OP voleva consultare le variazioni di prezzo di un singolo articolo
ed il risultato deve essere VELOCE !

ciao
fm



fm

unread,
Jul 7, 2013, 7:32:20 AM7/7/13
to

>da un punto di vista puramente logico anche a me sembra più
>corretto così. Anziché memorizzare tutte le informazioni su
>un'unica tabella, si fa una tabella Product con id e
>description, e si fa una tabella Product_Cost con id_product,
>date e cost.
>In fondo si tratta di due entità diverse, il prodotto e il
>costo, legate dall'id del prodotto.
>Tanto poi se c'è necessità di estrarre tutte le informazioni
>basta una semplice join.

anch'io avei fatto due tabelle...ma son preferenze individuali.

>Però non saprei assolutamente dire se così i tempi di lettura
>si riducono: io l'ho pensata da una prospettiva puramente
>logica.

e' mancata l'ANALISI ... ed hanno caricato nel db un sacco di bytes inutili
...

>Per quello che posso dire io, le query su tabelle con qualche
>migliaio o decine di migliaia di dati non sono istantanee,
>impiegano sempre un po' di secondi.
>Qui si parla invece di milioni di dati...

Io sposo la teoria di coloro che in questo thread hanno
fin dall'inizio consigliato ANCHE un controllo di tipo sistemistico
(Cpu, ram, configurazione di Mysql, etc etc)
Perche' anche dopo aver creato gli indici necessari
i tempi di risposta sono troppo alti.

Comunque ... la velocità, se serve, la ottieni DALL' HARDWARE e non dal
software.
Vedi mio post sotto...

CUT
>io come db conbosco mysql, oracle e sql server, e dei tre il
>paggiore mi sembra proprio mysql.
>Non può essere che con sql server o oracle, pur restando il
>discorso delle due tabelle, la situazione potrebbe migliorare?

Per quali motivi o esperienze (mia curiosità) dici che mysql e' il
peggiore?

ciao
fm


kojak

unread,
Jul 7, 2013, 10:17:02 AM7/7/13
to
Il giorno domenica 7 luglio 2013 13:32:20 UTC+2, fm ha scritto:
>
>
> >Per� non saprei assolutamente dire se cos� i tempi di lettura
> >si riducono: io l'ho pensata da una prospettiva puramente
> >logica.
>
>
> e' mancata l'ANALISI ... ed hanno caricato nel db un sacco di bytes inutili
> ...
>


ma no, cosa ti viene in mente? Ti pare possibile che si salti
l'analisi, o la si faccia a cazzo (se preferisci posso dire
"un tanto al chilo", per rendere lo stesso concetto in modo
meno rude)?

Sappiamo bene che le cose sono fatte sempre per bene e con tutto
il tempo necessario...



>
> >Per quello che posso dire io, le query su tabelle con qualche
> >migliaio o decine di migliaia di dati non sono istantanee,
> >impiegano sempre un po' di secondi.
> >Qui si parla invece di milioni di dati...
>
>
> Io sposo la teoria di coloro che in questo thread hanno
> fin dall'inizio consigliato ANCHE un controllo di tipo sistemistico
> (Cpu, ram, configurazione di Mysql, etc etc)
> Perche' anche dopo aver creato gli indici necessari
> i tempi di risposta sono troppo alti.
>


be', sì, le prestazioni chiaramente dipendono anche dalle
condizioni della macchina, sicuramente.
Ad ogni modo ribadisco quello che ho già detto, e cioè che
quando faccio delle query su tabelle con migliaia di dati
i tempi di risposta si allungano.



>
> >io come db conbosco mysql, oracle e sql server, e dei tre il
> >paggiore mi sembra proprio mysql.
> >Non pu� essere che con sql server o oracle, pur restando il
> >discorso delle due tabelle, la situazione potrebbe migliorare?
>
>
> Per quali motivi o esperienze (mia curiosit�) dici che mysql e' il
> peggiore?
>


intanto per la gestione delle funzioni e delle stored procedure:
la mia esperienza mi dice che è molto più agevole gestirle
con oracle e sql server che non con mysql.
Non che con mysql non si possano fare, intendiamoci, ma imo
non c'è paragone.
E poi le funzionalità messe a disposizione, le funzioni interne,
etc., mi sembra che anche da questo punto di vista gli altri due
prodotti siano più ricchi e più vari.



In compenso c'è una cosa che apprezzo molto di mysql: il fatto
che quando ad esempio su un set di risultati con 1000 righe
vuoi estrarre solo le righe, diciamo da 50 a 100 lo fai senza
alcun problema, poiché il limit ti permette di specificare
l'indice di inizio di estrazione dati e quanti dati vuoi
estrarre.
Per altri prodotti riesci a specificare con facilità quanti
dati tirare fuori, ma parti sempre dall'inizio: se voglio
estrarre i primi 50 dati riesco a farlo senza problemi,
ma se voglio estrarre i dati da 50 a 100 è più complicato,
questo intendo.
Invece con mysql col limit faccio tutto agevolmente.


Questo è molto utile ad esempio per la paginazione, quando
mostri i risultati su più pagine.

ispas

unread,
Jul 7, 2013, 12:02:16 PM7/7/13
to
Il giorno domenica 7 luglio 2013 12:41:50 UTC+2, kojak ha scritto:
> da un punto di vista puramente logico anche a me sembra più
>
> corretto così. Anziché memorizzare tutte le informazioni su
>
> un'unica tabella, si fa una tabella Product con id e
>
> description, e si fa una tabella Product_Cost con id_product,
>
> date e cost.

Sempre che non vari anche la descrizione. Magari non avviene da un giorno all'altro, ma dopo molti mesi potrebbe accadere.

ispas

unread,
Jul 7, 2013, 12:12:20 PM7/7/13
to
Il giorno domenica 7 luglio 2013 13:06:42 UTC+2, fm ha scritto:
>
> -----------------------------------------------------------------------------
>
> la macchina :
>
> IBM System x3650 M3,
>
> 2 cpu x Intel Xeon X5650 @ 2.67GHz (6 core)
>
> 16 GB DDR3
>
> 4 Hd 150Gb 15K SAS in raid 5
>
> -----------------------------------------------------------------------------

Tutto sta a vedere se quella applicazione dispone di un *vero* server, eventualmente dedicato al solo db, come quello che hai usato. Potrebbe essere il classico desktop promosso sul campo a server :-)


> L'errore fondamentale e' stato quello di inserire bovinamente tutte le righe
>
> giornalmente
>
> ricevute dal fornitore, anziche' le VARIAZIONI di prezzo.
>
> In quest'ultima maniera le righe sarebbero state 100-200K anzich� 14M in due
>
> anni.
>
> Quante variazioni di prezzo puo fare, in due anni, un fornitore che ha 18K
>
> referenze ?

Però se usassero il "tuo" server, con 15 milioni di righe, neppure se ne accorgerebbero di non avere la tabella superottimizzata logicamente (risposta in 0,1 ms). Che poi tale tabella di varaizioni va gestita con apposito applicativo di inserimento, mentre nell'altro modo butti dentro tutto direttamente. Pro e contro da valutare.

ispas

unread,
Jul 7, 2013, 12:20:19 PM7/7/13
to
Il giorno domenica 7 luglio 2013 16:17:02 UTC+2, kojak ha scritto:
> be', sì, le prestazioni chiaramente dipendono anche dalle
>
> condizioni della macchina, sicuramente.
>
> Ad ogni modo ribadisco quello che ho già detto, e cioè che
>
> quando faccio delle query su tabelle con migliaia di dati
>
> i tempi di risposta si allungano.

Diciamo che non sempre la struttura delle query ed il software applicativo sono perfetti... (eufemismo :-)

> Invece con mysql col limit faccio tutto agevolmente.

Magari perchè Mysql, furbescamente, in realtà legge tutte le prime X righe, ma semplicemente non te le restituisce. Un filtro sul modulo di output del db :-)
Solo un'ipotesi semiseria, ma in effetti è strano che altri db non diano questa possibilità.
In effetti, hai verificato se i tempi di risposta restano all'incirca uguali chiedendo N righe in posizioni diverse? Oppure si allungano in proporzione alla posizione di inizio?

AleTV

unread,
Jul 7, 2013, 12:22:31 PM7/7/13
to
"kojak" ha scritto nel messaggio
news:a755f770-648b-4603...@googlegroups.com...

> Per altri prodotti riesci a specificare con facilità quanti
> dati tirare fuori, ma parti sempre dall'inizio: se voglio
> estrarre i primi 50 dati riesco a farlo senza problemi,
> ma se voglio estrarre i dati da 50 a 100 è più complicato,
> questo intendo.
> Invece con mysql col limit faccio tutto agevolmente.
> Questo è molto utile ad esempio per la paginazione, quando
> mostri i risultati su più pagine.
>
Su sql dalla versione 2012 hanno aggiunto offset + fetch all'order by e fai
quello che fai con mysql:
http://msdn.microsoft.com/en-us/library/ms188385.aspx

ispas

unread,
Jul 7, 2013, 4:11:20 PM7/7/13
to
Il giorno domenica 7 luglio 2013 13:06:42 UTC+2, fm ha scritto:
> L'errore fondamentale e' stato quello di inserire bovinamente tutte le righe
>
> giornalmente
>
> ricevute dal fornitore, anziche' le VARIAZIONI di prezzo.
>
> In quest'ultima maniera le righe sarebbero state 100-200K anzich� 14M in due
>
> anni.
>
> Quante variazioni di prezzo puo fare, in due anni, un fornitore che ha 18K
>
> referenze ?

In realtà, oltre alle variazioni (perchè solo il prezzo e non anche la descrizione?) c'è l'ovvio caso di articoli che, nel tempo, si aggiungono o vengono eliminati. Altra informazione che richiede un aumento di complessità applicativa.

rootkit

unread,
Jul 7, 2013, 4:13:22 PM7/7/13
to
Il Sun, 07 Jul 2013 13:06:42 +0200, fm ha scritto:


>> certo se gli dai un server e dei dischi di ultima generazione peggio
>> non va,come direbbe il fù catalano.
>
> non e' che peggio non va....va meglio anzi MOLTO MEGLIO.

ah beh. il mio era un eufemismo, se non l'avevi notato.


> A riprova ho fatto un mini-test su di un "serverino" di due-tre anni fa
> ( allora non molto costoso ed oggi praticamente alla portata di tutti,
> l'hw x86 praticamente te lo dirano dietro).
>
> I risultati in termini di prestazioni, rispetto a quelli riportati
> dall'OP, sono IMPIETOSI.

i risultati postati dall'op sono viziati da numerosi errori, sono
abbastanza confidente che anche una volta corretti quegli errori il
confronto diventerà impietoso. dico anche che ovviare con più potenza di
calcolo alle scarse performance di codice "pessimizzato" non la trovo una
cosa ben fatta.

> ci credo ma e' un caso diverso .... si tratta di centinaia o migliaia di
> oggetti di grandi dimensioni.
> Quella dell'OP e' una tabella di decine di milioni di righe da circa 400
> (?) byte

una query secca su una tabella correttamente progettata, popolata e
indicizzata ha tempi di accesso costanti. questo mi hanno insegnato
essere una delle competenze del dba...


>>certo che se uno i dati li struttura a capocchia o inserisce
>> badilate di righe inutili è possibile che poi per ricercarli servano
>> otto core,
> Ovviamente: merd-in merd out ...
> L'errore fondamentale e' stato quello di inserire bovinamente tutte le
> righe giornalmente ricevute dal fornitore, anziche' le VARIAZIONI di
> prezzo.
> In quest'ultima maniera le righe sarebbero state 100-200K anzichè 14M in
> due anni.

non solo, sarebbero anche più ricercabili.

>>però qualsiasi programma di magazzino per fare la valorizzazione
>> deve andare a leggere i listini ad una data e non mi pare che girino
>> tutti su server di ultima generazione...
>>
> c'entra poco o nulla.
> In genere quando si fa una valorizzazione di magazzino non si sta col
> cronomentro in mano a misurare i tempi (vale per il sw della Finson a
> 29.90 euro e per il SAP)

vero, ma se per fare il prezzo ad una data ci mette un tempo dell'ordine
dei secondi più che il cronometro ti serve il calendario...

rootkit

unread,
Jul 7, 2013, 4:48:04 PM7/7/13
to
Il Sun, 07 Jul 2013 09:20:19 -0700, ispas ha scritto:


>> Invece con mysql col limit faccio tutto agevolmente.
>
> Magari perchè Mysql, furbescamente, in realtà legge tutte le prime X
> righe, ma semplicemente non te le restituisce. Un filtro sul modulo di
> output del db :-)

ovviamente il costo è quello della query non limitata, se non altro
perché se deve restituire un subset di dati ordinato l'ordinamento lo
dovrà fare sull'intero resultset.

Enrico 'Henryx' Bianchi

unread,
Jul 7, 2013, 7:18:03 PM7/7/13
to
Daniele Orlandi wrote:

> - Le chiavi private devono essere opache e compatte

Cosa intendi per "chiave privata" ed "opaca" (per compatta direi che sia
semplice, visto che un VARCHAR(128) non e` una chiave per definizione)

> - Gli ID per collegare i record devono essere compatti e opachi

Idem come sopra

> - Non si usano i floating point per memorizzare prezzi

In effetti e` piu` corretto usare un NUMERIC

> 14 milioni di record non sono nulla di folle

Concordo, anche se comincerei comunque a valutare una forma di
partizionamento dei dati (molto dipende dal DBMS che si utilizza)

Enrico

Luca Menegotto

unread,
Jul 8, 2013, 3:37:00 AM7/8/13
to
Il giorno domenica 7 luglio 2013 18:02:16 UTC+2, ispas ha scritto:

> Sempre che non vari anche la descrizione. Magari non avviene da un giorno all'altro, ma dopo molti mesi potrebbe accadere.

Avevo pensato alla stessa cosa ma, a guardare la tabella iniziale, sembra non succedere. Intendo: non c'è un codice articolo e una descrizione, c'è solo un campo descrizione, il che mi fa pensare che nel tempo non cambi; non ne conosciamo il contenuto: potrebbe essere anche un codice derivato da bar code...

--
Ciao!
Luca

Luca Menegotto

unread,
Jul 8, 2013, 3:39:43 AM7/8/13
to
Il giorno domenica 7 luglio 2013 22:11:20 UTC+2, ispas ha scritto:

> In realtà, oltre alle variazioni (perchè solo il prezzo e non anche la descrizione?) c'è l'ovvio caso di articoli che, nel tempo, si aggiungono o vengono eliminati. Altra informazione che richiede un aumento di complessità applicativa.

Vero. In effetti bisogna lavorare di bilancia: su un piatto butti la complessità applicativa, sull'altro la quantità di dati da trattare, e vedi che ne viene fuori.

--
Ciao!
Luca

ispas

unread,
Jul 8, 2013, 3:50:27 AM7/8/13
to
Poi di solito la complessità applicativa ha un costo maggiore della complessità hardware (cioè: paghi di più per lo sviluppo software che per l'uso più intenso od il potenziamento dell'hardware). Detto questo, la soluzione "banale" attuale potrebbe non essere la peggiore. Magari spendono qualche centone per hardware un poco migliore, ed hanno risolto. Lavoro di meno per gli sviluppatori, certo :-)

ispas

unread,
Jul 8, 2013, 3:52:06 AM7/8/13
to
Il giorno domenica 7 luglio 2013 22:48:04 UTC+2, rootkit ha scritto:
> ovviamente il costo è quello della query non limitata, se non altro
>
> perché se deve restituire un subset di dati ordinato l'ordinamento lo
>
> dovrà fare sull'intero resultset.

E se non deve fare nessun ordinamento speciale, solo l'ordine di un indice? Chiedo, perchè non ho mai usato Mysql.

Luca Menegotto

unread,
Jul 8, 2013, 4:08:52 AM7/8/13
to
Il giorno lunedì 8 luglio 2013 01:18:03 UTC+2, Enrico 'Henryx' Bianchi ha scritto:

> semplice, visto che un VARCHAR(128) non e` una chiave per definizione

Oh bella, e questa affermazione così perentoria da dove arriva?

--
Ciao!
Luca

Francesco Da Riva

unread,
Jul 8, 2013, 4:28:29 AM7/8/13
to
On Monday, July 8, 2013 10:08:52 AM UTC+2, Luca Menegotto wrote:

>
> Oh bella, e questa affermazione così perentoria da dove arriva?

Guarda personalmente sottoscrivo questo: http://www.soft-land.org/documenti/pk

Ciao
Francesco

Suarez

unread,
Jul 8, 2013, 4:42:39 AM7/8/13
to
On Fri, 05 Jul 2013 09:22:17 +0200, ga.n <ga...@askme.invalid> wrote:


>CREATE TABLE `products` (
> `file_date` date NOT NULL,
> `supplier_id` varchar(128) NOT NULL,
> `description` varchar(255) DEFAULT NULL,
> `cost` double(10,2) DEFAULT NULL,
> PRIMARY KEY (`file_date`,`supplier_id`),
>) ENGINE=InnoDB;
>

Sono l'unico a pensare che un varchar(128) come chiave primaria sia un obrobrio?
Da come lavori la query quasi sicuramente viene fato un full table scan, quello
associato al varchar e alla mancanza di indici appropriati e' la prima causa
della lentezza, crea un vero id prodotto (intero o char fa poca differenza ma
non varchar) io ho tabelle prodotto con il codice char di 15 o 20 caratteri,
tabelle con svariati milioni di record, ma tempi assolutamente congrui, poi
oltre un certo limite l'ottimizzazione non puo' che essere hw quindi o si rimane
su MySql cambiando server (o rivedendone la cofigurazione per memoria allocabile
e potenza cpu assegnata) o si cambia MySql proprio.

Luca Menegotto

unread,
Jul 8, 2013, 4:59:45 AM7/8/13
to
Il giorno lunedì 8 luglio 2013 10:28:29 UTC+2, Francesco Da Riva ha scritto:

> Guarda personalmente sottoscrivo questo: http://www.soft-land.org/documenti/pk

Lo conosco da molto tempo. E' un po' la diatriba tra chi è purista della teoria relazionale, e chi pensa che una specie di indice come chiave primaria sia sempre un bene. Personalmente io sto dalla parte del buon Davide: in medio stat virtus! Ci sono situazioni in cui è sensato usare indici come chiavi primarie (a proposito, io impiego dei GUID), altre in cui è opportuno impiegare uno o più campi che, si sa in partenza, non verranno modificati nel tempo.

NOTA. Volendo entrare nel merito, proprio per come è costruito, il varchar non è il massimo dal punto di vista prestazionale; tuttavia - prove svolte su PostgreSql e su SQLServer - non c'è poi questa grande differenza, almeno su 6 milioni di record circa.

--
Ciao!
Luca

ispas

unread,
Jul 8, 2013, 5:22:28 AM7/8/13
to
Il giorno lunedì 8 luglio 2013 10:59:45 UTC+2, > > NOTA. Volendo entrare nel merito, proprio per come è costruito, il varchar non è il massimo dal punto di vista prestazionale; tuttavia - prove svolte su PostgreSql e su SQLServer - non c'è poi questa grande differenza, almeno su 6 milioni di record circa.

Penso che dipenda anche molto dal grado di riempimento del campo. Un codice fiscale definito Varchar che è sempre di 16 caratteri non degrada le prestazioni come un varchar di 128 riempito solo parzialmente. Forse perchè l'albero binario dell'indice, o struttura analoga, è molto più complesso?

Suarez

unread,
Jul 8, 2013, 10:57:27 AM7/8/13
to
On Mon, 8 Jul 2013 01:59:45 -0700 (PDT), Luca Menegotto
<menegot...@gmail.com> wrote:


>NOTA. Volendo entrare nel merito, proprio per come è costruito, il varchar non è il massimo dal punto di vista prestazionale;

Appunto. poi occorre distinguere se la tabella ha pochi a trillairdi di record,
indici strutturati ecc ecc. Dopo 20 anni che lavoro con i db solo una cosa ho
imparato: che non esiste una soluzione miracolosa che abbatte i tempi o i
problemmi da 100 a zero in pochi passi, e' tutto un limare a destra e a manca...

Nel merito io pure in certe situazioni ha chiavi char(15) o Char(20) che non
danno problemi di sorta, un varchar(128) dimostra un certo grado di
incoscenza...

rootkit

unread,
Jul 8, 2013, 11:19:16 AM7/8/13
to
Il giorno lunedì 8 luglio 2013 16:57:27 UTC+2, Suarez ha scritto:


> Nel merito io pure in certe situazioni ha chiavi char(15) o Char(20) che non
> danno problemi di sorta, un varchar(128) dimostra un certo grado di
> incoscenza...

scusa l'ignoranza, ma in che senso? qual'è il problema degli indici di varchar?

ga.n

unread,
Jul 8, 2013, 11:28:31 AM7/8/13
to
Stavamo scarsi a Cretinetty, mancava solo Luca Menegotto con l'idea:
il campo `supplier_id` non contiene, come si potrebbe *ingenuamente*
pensare, l'id del fornitore ma il codice che il fornitore assegna al
prodotto

che io capisco fare le cose di fretta, capisco tutto ma almeno i nomi
dei campi si possono mettere con un minimo di buon senso ...

--
avevo la foto di una palla da neve che avevo cominciato a far rotolare
all'inizio della camminata di ritorno verso le macchine. all'arrivo al
posteggio la palla da neve era piu' grossa di tafano e piu' alta di
fabmind.


AleTV

unread,
Jul 8, 2013, 3:11:50 PM7/8/13
to
"rootkit" ha scritto nel messaggio
news:42059c52-8e43-49cf...@googlegroups.com...
Parlava di chiavi, non di "semplici" indici.
E se magari la chiave è pure clustered hai tutti gli altri indici pesanti di
conseguenza.

rootkit

unread,
Jul 8, 2013, 5:49:06 PM7/8/13
to
Il Mon, 08 Jul 2013 21:11:50 +0200, AleTV ha scritto:


>>> Nel merito io pure in certe situazioni ha chiavi char(15) o Char(20)
>>> che non danno problemi di sorta, un varchar(128) dimostra un certo
>>> grado di incoscenza...
>>
>>scusa l'ignoranza, ma in che senso? qual'è il problema degli indici di
>>varchar?
>>
> Parlava di chiavi, non di "semplici" indici.
> E se magari la chiave è pure clustered hai tutti gli altri indici
> pesanti di conseguenza.

cambio la domanda: qual'è il problema delle chiavi varchar (rispetto ai
char, a questo punto)?

Enrico 'Henryx' Bianchi

unread,
Jul 8, 2013, 6:35:07 PM7/8/13
to
rootkit wrote:

> penso che se ci sono gli indici giusti non c'è
> motivo di sedersi, è vero che esegue molte volte la subqery che però
> dovrebbe essere istantanea visto che rimane sempre sull'indice.

Vero, ma e` vero anche che con MySQL tutto e` possibile :)
Per dire, nella query da te postata, MySQL fa prima un index scan per la
parte in subquery e poi un full scan per il resto. Diversamente, PostgreSQL
fa sempre un index scan, sia per la parte in subquery, sia per la parte
esterna

Enrico

fm

unread,
Jul 9, 2013, 1:20:49 AM7/9/13
to

>
> cambio la domanda: qual'è il problema delle chiavi varchar (rispetto ai
> char, a questo punto)?

in Sql server vengono usati 2 byte in piu'...ovvero "pesano" di piu'...

Non so se lo stesso succede in MySql ...

ciao
fm


Suarez

unread,
Jul 9, 2013, 2:53:54 AM7/9/13
to
On Mon, 8 Jul 2013 21:49:06 +0000 (UTC), rootkit wrote:

>cambio la domanda: qual'è il problema delle chiavi varchar (rispetto ai
>char, a questo punto)?

sono piu' pesanti, db2 e sqlserver (ma credo anche Oracle) aggiungono due byte,
uno crede di risparmiare invece aumenta il peso del proprio db, su db2 (il
sistema che conosco meglio) l'allocazione dello storage di sistema e' data dalla
lunghezza massima del campo (128 in questo caso) + due byte.
Il motore sql che procede all'ordinamento "fatica" di piu' (dacche' e' cosa
buona avere almeno un index sul campo chiave).
Se per sbaglio fai una query che comporta un full table scan allora ti diverti
proprio :-)
VarChar mi hanno insegnato all'epoca va usato com molto discernimento, per campi
descrittivi e proprio quando non se ne puo' fare a meno (lo standard ai bei
tempi era che le descrizioni brevi fossere Char(25) quelle lunghe Char(35)).
E' vero che la potenza hardware compensa e maschera la situazione, ma al
crescere del numero di record (qualche milione come nell'esempio dell'op) il db
va in panne ugualmente.

ispas

unread,
Jul 9, 2013, 3:39:16 AM7/9/13
to
Il giorno martedì 9 luglio 2013 00:35:07 UTC+2, Enrico 'Henryx' Bianchi ha scritto:
> Vero, ma e` vero anche che con MySQL tutto e` possibile :)
>
> Per dire, nella query da te postata, MySQL fa prima un index scan per la
>
> parte in subquery e poi un full scan per il resto. Diversamente, PostgreSQL
>
> fa sempre un index scan, sia per la parte in subquery, sia per la parte
>
> esterna

In Oracle "comanda" l'ottimizzatore (che non è un burocrate, ma un modulo interno :-), decide lui se usare o no un indice in base ai parametri di costo. Di default il tempo di risposta non è il parametro principale (si valutano occupazione di memoria, traffico sulla rete, frammentazione dello spazio fisico, ed altro). Per forzare l'uso di un indice bisogna scrivere la select con speciali parametri (hints).
Può essere che Mysql operi allo stesso modo.

ispas

unread,
Jul 9, 2013, 3:43:15 AM7/9/13
to
Il giorno martedì 9 luglio 2013 08:53:54 UTC+2, Suarez ha scritto:
> On Mon, 8 Jul 2013 21:49:06 +0000 (UTC), rootkit wrote:
>
>
>
> >cambio la domanda: qual'� il problema delle chiavi varchar (rispetto ai
Se aggiunge solo 2 bytes su 128 non mi sembra ci sia uno "scoppio" dello spazio necessario, e relativa potenza di calcolo. Vedo più il problema nel caso in cui l'occupazione dei 128 bytes sia effettivamente molto variabile, a quel punto il db è costretto ad allocare e gestire spazi ugualmente variabili con quel che consegue.

Suarez

unread,
Jul 9, 2013, 4:20:13 AM7/9/13
to
On Tue, 9 Jul 2013 00:43:15 -0700 (PDT), ispas <gid...@interfree.it> wrote:


> Vedo piů il problema nel caso in cui l'occupazione dei 128 bytes sia effettivamente molto variabile, a quel punto il db č costretto ad allocare e gestire spazi ugualmente variabili con quel che consegue.

il punto e' questo, se i 128 fossero sempre pieni, paradossalmente il motore db
faticherebbe molto di meno

AleTV

unread,
Jul 9, 2013, 4:00:24 PM7/9/13
to
"Suarez" ha scritto nel messaggio
news:4acnt85kvkm9s9shd...@4ax.com...

> sono piu' pesanti, db2 e sqlserver (ma credo anche Oracle) aggiungono due
> byte,
> uno crede di risparmiare invece aumenta il peso del proprio db, su db2 (il
> sistema che conosco meglio) l'allocazione dello storage di sistema e' data
> dalla
> lunghezza massima del campo (128 in questo caso) + due byte.
> Il motore sql che procede all'ordinamento "fatica" di piu' (dacche' e'
> cosa
> buona avere almeno un index sul campo chiave).
>
Non mi risulta, nel senso che per tenere memorizzati campi a lunghezza
variabile con i varchar risparmi spazio e fai fare anche all'engine metto
attività di i/o proprio perché lo spazio usato è quello che serve (oltre ai
2 bytes di overhead che fanno da metadato per sapere la lunghezza del
singolo valore).
Ovviamente questo è vero solo se i dati che devi memorizzare hanno appunto
una lunghezza variabile e non sono per la maggior parte vicini vicini al
valore "nominale".
Per il caso specifico comunque anche io sono tra quelli che considera una pk
su un campo varchar(128) una cagata pazzesca.

> Se per sbaglio fai una query che comporta un full table scan allora ti
> diverti
> proprio :-)
>
Dipende, metti che la maggior parte dei dati sono grandi attorno alla metà
del valore massimo, hai meno attività di i/o usando un varchar() piuttusto
che un char().

AleTV

unread,
Jul 9, 2013, 4:03:33 PM7/9/13
to
"Suarez" ha scritto nel messaggio
news:jlgnt8h81qsfuh9ta...@4ax.com...
> On Tue, 9 Jul 2013 00:43:15 -0700 (PDT), ispas <gid...@interfree.it>
> wrote:
>
>
>> Vedo più il problema nel caso in cui l'occupazione dei 128 bytes sia
>> effettivamente molto variabile, a quel punto il db è costretto ad
>> allocare e gestire spazi ugualmente variabili con quel che consegue.
>
> il punto e' questo, se i 128 fossero sempre pieni, paradossalmente il
> motore db
> faticherebbe molto di meno
>
Se sul serio i dati sono variabili fino a 128 bytes massimi e nel concreto
la variabilità esiste davvero e non è solo sulla carta, il numero di pagine
che l'engine si deve tirar su per accedere ai dati è inferiore nel caso di
utilizzo di varchar piuttosto che char, ergo l'engine è ben felice di
risparmiare spazio nella sua prezioa cache dove tiene i dati a cui accede
per risolvere le query.

Marcoxxx

unread,
Jul 10, 2013, 8:41:48 AM7/10/13
to
AleTV ha scritto:

> "Suarez" ha scritto nel messaggio
> news:4acnt85kvkm9s9shd...@4ax.com...


> >
> Non mi risulta, nel senso che per tenere memorizzati campi a lunghezza
> variabile con i varchar risparmi spazio e fai fare anche all'engine metto
> attività di i/o proprio perché lo spazio usato è quello che serve (oltre ai
> 2 bytes di overhead che fanno da metadato per sapere la lunghezza del
> singolo valore).
> Ovviamente questo è vero solo se i dati che devi memorizzare hanno appunto
> una lunghezza variabile e non sono per la maggior parte vicini vicini al
> valore "nominale".

In realta' comunque l'I/O effettivamente eseguito dipende anche da
variabili ben difficilmente valutabili a priori (nella mia test di laurea
ad esempio si cercava di valutare, tra le altre cose, l'effetto della
scelta di una policy LRU piuttosto che MRU per la scelta di quali pagine
scaricare dalla memoria in caso di page fault. E anche la scelta di una
policy piuttosto che un'altra può portare a piu' o meno page faults. E non
e' che sia facile capire "a priori" quale e' la policy migliore)

> Per il caso specifico comunque anche io sono tra quelli che considera una pk
> su un campo varchar(128) una cagata pazzesca.

Pero' non e' chiaro quali siano secondo te i motivi per considerarla cosi',
visto che i motivi addotti da altri non sembrano convincerti.

Ciao,
Marco.

--

questo articolo e` stato inviato via web dal servizio gratuito
http://www.newsland.it/news segnala gli abusi ad ab...@newsland.it


FP

unread,
Jul 10, 2013, 9:08:20 AM7/10/13
to

>> Per il caso specifico comunque anche io sono tra quelli che considera una pk
>> su un campo varchar(128) una cagata pazzesca.
>
> Pero' non e' chiaro quali siano secondo te i motivi per considerarla cosi',
> visto che i motivi addotti da altri non sembrano convincerti.


Ho letto il thread tutto d'un fiato oggi perché questo tipo di problemi
di ottimizzazione mi sono sempre interessati (anche se poi magari non ne
ho le competenze).

Se avessi il compito di riprogettare il db e la possibilità contestuale
di rivedere l'applicazione procederei nel mettere in pratica diversi
test, uno dei quali è quello di sostituire la chiave varchar in un id
numerico.

L'uso di un id numerico permette al db di:
- eventualmente ottimizzare l'accesso all'indice in quanto tutte le
chiavi hanno la stessa lunghezza
- inserire più chiavi in ogni blocco dell'indice (considerando un indice
btree*) quindi la possibilità di dover accedere ad un numero inferiore
di pagine
- più veloce comparazione fra i valori degli indici perché non si
arriverà mai a 128 bytes ma al massimo 8 per un intero veramente grande...

Se poi si procedesse con una normalizzazione più spinta, con i varchar
inseriti in un'altra tabella, ti ritroveresti una tabella con lunghezza
record fissa a circa 40 caratteri, ovvero 560 MB... con il vantaggio che
magari se lo tiene in memoria il file...


Io partirei dalla fine, definendo i seguenti parametri:
- quali sono le query che si vogliono far girare più spesso oppure
- entro quali tempi devono fornire una risposta (2 secondi possono
essere accettabili per una risposta interattiva ma se devo fare la
stessa ricerca in batch su 10.000 codici mi diventa impossibile....)
- su quale hardware devo far girare il tutto ovvero quanti fondi sono
stanziati per un hardware più veloce....


poi viene tutto il resto....

FP

unread,
Jul 10, 2013, 9:21:20 AM7/10/13
to

> questa informazioni la vedo con EXPLAIN giusto?
>
> ad esempio in questo caso
>
> http://pastebin.com/SFrRR1jy
>
> sono 330?

Gentilmente mi potresti dire quali sono gli indici attivi al momento
della EXPLAIN ?

Esiste un indice composto supplier_id, file_date ? Se non esiste
potresti crearlo e ripetere la EXPLAIN ?

ga.n

unread,
Jul 10, 2013, 10:19:38 AM7/10/13
to
FP ha pensato forte :
>> questa informazioni la vedo con EXPLAIN giusto?
>>
>> ad esempio in questo caso
>>
>> http://pastebin.com/SFrRR1jy
>>
>> sono 330?

> Gentilmente mi potresti dire quali sono gli indici attivi al momento della
> EXPLAIN ?

(supplier_id, file_date) e supplier_id





--
è la visione hopperiana di una transumansa quotidiana di sentimenti
digitali che altrimenti potremmo definire fottesega


ga.n

unread,
Jul 10, 2013, 10:25:07 AM7/10/13
to
Nel suo scritto precedente, FP ha sostenuto :
> Io partirei dalla fine, definendo i seguenti parametri:
> - quali sono le query che si vogliono far girare più spesso oppure
> - entro quali tempi devono fornire una risposta (2 secondi possono essere
> accettabili per una risposta interattiva ma se devo fare la stessa ricerca in
> batch su 10.000 codici mi diventa impossibile....)

sto facendo proprio così

pensavo anche di metter su postgresql

> - su quale hardware devo far girare il tutto ovvero quanti fondi sono
> stanziati per un hardware più veloce....

e la risposta è (rullo di tamburi) "possiamo mettere un po' di ram in
più"

--
Nel '94 votai Berlusconi perchè mi feci imbambolare dalla discesa in
campo.
Ero davvero convinto che sarebbe tutto cambiato rispetto agli anni di
Andreotti/Craxi
(Soprano, IAT, 26/03/2010


FP

unread,
Jul 10, 2013, 11:45:51 AM7/10/13
to

>> Gentilmente mi potresti dire quali sono gli indici attivi al momento
>> della EXPLAIN ?
>
> (supplier_id, file_date) e supplier_id

scusa se insisto ma chiedo conferma visto che nel messaggio originale
dicevi:
PRIMARY KEY (`file_date`,`supplier_id`) e non supplier_id, file_date

Hai la possibilità di modificare il software che fa le query ? Perché
magari potresti spezzare la query in più parti ottimizzandole
separatamente ?
Ad esempio potresti fare una prima query per prendere le prime 10 date
(o la min(file_date) fra queste 10) e poi fare la select chiedendo quel
codice prototto AND che la data sia fra quelle indicate (o >= la data
trovata). Dovresti in questo modo poter sfruttare appieno gli indici e
poi il sort avviene su 10 record e non su 330.

Il secondo esperimento è magari quello di provare a usare codici ID
numerici al posto di varchar(128) come chiavi e indici per le
ottimizzazioni di cui si parlava prima.

Immagino poi che non sia possibile avere il file, nemmeno in formato
anonimizzato (importi a 0, descrizioni a "Prodotto X", codici a
"CODXXXXXXX", ovviamente con lo stesso codice reale abbinato allo stesso
CODXXXXXXX così che si possa ripetere la stessa query della EXPLAIN...)





FP

unread,
Jul 10, 2013, 11:49:06 AM7/10/13
to

> pensavo anche di metter su postgresql

Quali benefici pensi di ottenere da postgresql ?


>
>> - su quale hardware devo far girare il tutto ovvero quanti fondi sono
>> stanziati per un hardware più veloce....
>
> e la risposta è (rullo di tamburi) "possiamo mettere un po' di ram in più"


Sai, se il server ora ha 256 mega di ram ben venga l'espansione... se ne
ha 16 GB... non mi sembra di aver letto nulla sulla configurazione hw/sw
su cui gira il server, se è un db server dedicato o il pc della
segretaria...

E già hanno chiesto di verificare la configurazione di mysql...

io penserei anche a passare da innodb a qualche altro metodo di storage
più veloce...


ga.n

unread,
Jul 10, 2013, 1:33:18 PM7/10/13
to
FP ha usato la sua tastiera per scrivere :
>> pensavo anche di metter su postgresql

> Quali benefici pensi di ottenere da postgresql ?

>>
>>> - su quale hardware devo far girare il tutto ovvero quanti fondi sono
>>> stanziati per un hardware più veloce....
>>
>> e la risposta è (rullo di tamburi) "possiamo mettere un po' di ram in più"

> Sai, se il server ora ha 256 mega di ram ben venga l'espansione... se ne ha
> 16 GB... non mi sembra di aver letto nulla sulla configurazione hw/sw su cui
> gira il server, se è un db server dedicato o il pc della segretaria...

# cat /proc/cpuinfo
vendor_id : GenuineIntel
cpu family : 6
model : 37
model name : Intel(R) Pentium(R) CPU G6950 @ 2.80GHz
stepping : 2
cpu MHz : 2793.000
cache size : 3072 KB

# cat /proc/meminfo
MemTotal: 3945864 kB


questo pc fa:

- database server,
- scarica i listini e li importa nel loro gestionale (questo lo fa di
notte quindi non incide nel normale carico del server)
- fa girare un paio di applicazioni in python tramite apache/wsgi

quindi niente di particolarmente "stressante"

> E già hanno chiesto di verificare la configurazione di mysql...

> io penserei anche a passare da innodb a qualche altro metodo di storage più
> veloce...

pensavo di sostituire mysql con postgresql (non vogliono spendere in
hardware figuriamoci in software)

sul confronto tra i due ho sempre letto articoli che avevano un
retrogusto di "fan boy" se hai qualche articolo da suggerirmi lo
leggerei con piacere

fermo restando che che "butterò" la tabella esistente e creerò uno
schema più ragionato.

--
non ci si puo' leticare con brancaleone.
e' come prendersela con un handicappato.


AleTV

unread,
Jul 10, 2013, 3:17:11 PM7/10/13
to
"Marcoxxx" ha scritto nel messaggio news:krjkl7$3r7$1...@news.newsland.it...

> In realta' comunque l'I/O effettivamente eseguito dipende anche da
> variabili ben difficilmente valutabili a priori (nella mia test di laurea
> ad esempio si cercava di valutare, tra le altre cose, l'effetto della
> scelta di una policy LRU piuttosto che MRU per la scelta di quali pagine
> scaricare dalla memoria in caso di page fault. E anche la scelta di una
> policy piuttosto che un'altra può portare a piu' o meno page faults. E non
> e' che sia facile capire "a priori" quale e' la policy migliore)
>
Parlo per ms sql server per esperienza diretta: l'accesso ai dati da parte
del modulo che risolve la query avviene solo nella cache dati interna di
sql, se per risolvere una query i dati non sono in cache allora prima
vengono per forza letti da disco. Più una query ha bisogno di tirar su
pagine (ogni pagina sono un 8KB), più attività di I/O genera quando quei
dati non sono già in cache. Meno pagine servono, meno attività viene fatta
(e questo è il motivo per cui una query "a freddo" impiega più tempo per
essere eseguita rispetto a chiamate successive, la differenza è proprio il
tempo che server all'engine a recuperare le pagine da disco di cui la query
necessita) e più veloce è la query.

>> Per il caso specifico comunque anche io sono tra quelli che considera una
>> pk
>> su un campo varchar(128) una cagata pazzesca.
>
> Pero' non e' chiaro quali siano secondo te i motivi per considerarla
> cosi',
> visto che i motivi addotti da altri non sembrano convincerti.
>
Parlavo della differenza in generale tra i varchar() e i char() a livello di
occupazione, ma questo non vuole dire che un varchar(128) anche con dati
che internamente sono davvero variabili essendo meglio da un punto di vista
di occupazione di spazio e quindi attività di lettura/scrittura di pagine di
dati rispetto ad un char(128) sia una buona scelta come chiave primaria...
visto che le pk spesso sono usate come chiavi esterne in altre tabelle hai
qui si molto overhead in più per far gestire l'integrità dei dati
direttamente al motore tramite DRI. E come accennavo, visto che di default è
così, se la pk sotto è anche un indice clustered, hai anche tutti gli altri
indici di quella tabella che occupato molto spazio visto che hanno in pancia
le chiavi dell'indice clustered che appunto servono per referenziare le
singole righe della tabella, e il tutto si traduce ancora alla fine in molta
attività di i/o per il motore.

AleTV

unread,
Jul 10, 2013, 3:20:41 PM7/10/13
to
"FP" ha scritto nel messaggio news:krjmc6$kgq$1...@newsreader2.mclink.it...

> Io partirei dalla fine, definendo i seguenti parametri:
> - quali sono le query che si vogliono far girare più spesso oppure
> - entro quali tempi devono fornire una risposta (2 secondi possono essere
> accettabili per una risposta interattiva ma se devo fare la stessa ricerca
> in batch su 10.000 codici mi diventa impossibile....)
> - su quale hardware devo far girare il tutto ovvero quanti fondi sono
> stanziati per un hardware più veloce....
>

Eh, ci vorrebbe nostradamus per sapere a priori quali sono le query che
girano più spesso... :-)
Infatti di solito si fa alla rovescia, nel senso che con ambiente in uso
reale si monitorano le query utilizzate per sapere dove ha più senso
intervenire, visto che potrebbe capitare di dover metter mano a una query
che gira in 100 ms ma che viene chiamata una milionata di volte al giorno
piuttosto che dedicare tempo ad una query che gira in 2 minuti ma che viene
usata 10 volte nella giornata.

FP

unread,
Jul 10, 2013, 3:48:53 PM7/10/13
to
Stiamo dicendo la stessa cosa ??? :-))))

> Eh, ci vorrebbe nostradamus per sapere a priori quali sono le query che
> girano più spesso... :-)

Lui l'applicazione già ce l'ha, ha dentro i dati, se non ho capito male,
di 2 anni... una query l'ha pubblicata ed è già passato da 12 a 2
secondi solo aggiungendo un indice. Poi io ritengo che possa ancora
migliorare splittando la query in due parti, ma occorrerebbe avere più
informazioni (sul db e sulle conoscenze e libertà di azione del
programmatore).

Nottetempo il sistema prende questo file con dentro Xmila linee e lo
carica, creando Xmila nuovi record. Ma poi la ricerca avviene solo ed
esclusivamente selezionando un codice prodotto e studiandone l'andamento
nel tempo. Se fosse solo questo ciò che si vuole ottenere uno potrebbe
pensare di stravolgere tutto il db... una follia sarebbe quella di
creare una tabella per ogni codice prodotto... in 2 anni avresti 730
record e la query sarebbe istantanea... A quel punto basterebbe un file
ASCII, un file per ogni codice prodotto, che ti leggi e ordini in
memoria quando ti serve (in realtà è già ordinato per data e se crei
record a dimensione fissa....)
Per ultimo si potrebbe pensare a database nosql nelle varie tipologie...
per la quantità di dati in gioco attualmente un db chiave - valore dove
per valore intendi un array con l'andamento dei prezzi...



> Infatti di solito si fa alla rovescia, nel senso che con ambiente in uso
> reale si monitorano le query utilizzate per sapere dove ha più senso
> intervenire, visto che potrebbe capitare di dover metter mano a una
> query che gira in 100 ms ma che viene chiamata una milionata di volte al
> giorno piuttosto che dedicare tempo ad una query che gira in 2 minuti ma
> che viene usata 10 volte nella giornata.

E' esattamente quello che dicevo e il risultato di questa analisi, come
ho scritto sopra, potrebbe pure portare a stravolgere l'impostazione del
database !
>

FP

unread,
Jul 10, 2013, 4:03:51 PM7/10/13
to
Il 10/07/2013 19.33, ga.n ha scritto:
>
> fermo restando che che "butterò" la tabella esistente e creerò uno
> schema più ragionato.


Questa è la prima prova che devi fare. La macchina sembra ok, per quello
che devi fare. Dovresti portare la tabella nettamente sotto il giga,
almeno la parte indici, così che non debba leggere le pagine dal disco !

Ti invito anche a leggere questo articolo che fornisce degli hint
interessanti e dei suggeriemnti per prove da effettuare, nonché degli
spunti per approfondimenti.


ispas

unread,
Jul 11, 2013, 4:44:50 AM7/11/13
to
Il giorno mercoledì 10 luglio 2013 15:08:20 UTC+2, FP ha scritto:
> Io partirei dalla fine, definendo i seguenti parametri:
>
> - quali sono le query che si vogliono far girare più spesso oppure
>
> - entro quali tempi devono fornire una risposta (2 secondi possono
>
> essere accettabili per una risposta interattiva ma se devo fare la
>
> stessa ricerca in batch su 10.000 codici mi diventa impossibile....)
>
> - su quale hardware devo far girare il tutto ovvero quanti fondi sono
>
> stanziati per un hardware più veloce....

In verità, quando si analizzano i dati, queste domande non sono la fine, ma sono l'inizio... :-)
In genere, poi, si dovrebbe prima fare un'analisi della pura struttura logica, eventualmente normalizzata al massimo grado. Successivamente fare una progettazione legata ai vincoli hardware, linguaggio, dbms, ecc.

Daniele Orlandi

unread,
Jul 13, 2013, 6:53:53 PM7/13/13
to
AleTV wrote:
>
> Su sql dalla versione 2012 hanno aggiunto offset + fetch all'order by e
> fai quello che fai con mysql:
> http://msdn.microsoft.com/en-us/library/ms188385.aspx

Ohssantamaria.... spero di non aver capito la ratio di quel coso... ma l'uso
dell'indice per ottenere un subset ordinato e limitato senza un full-scan è
compito del *planner* non del linguaggio....
0 new messages