Newsgroup: it.comp.www.php
Titolo: applicativo php+mysql ingestibile

Ciao a tutti.
Io e un mio amico abbiamo realizzato un applicativo gestionale web in
php+mysql. L'azienda ha cominciato a lavorarci e adesso stanno nascendo
i primi problemi diciamo di "volume". Cerco di spiegarvi meglio: il
problema nasce soprattutto nella costruzione di un grafico; una tabella
carichi_lavoro contiene dati sugli operai che vengono matchati con la
tabella degli operai per ricavare altri dati e ancora con una tabella
di percentuali che vanno applicati...insomma alla fine per costruire
questo grafico occorrono 6 minuti (che mi sembrano un tempo
inaccettabile). Il problema non è legato al grafico (generato con
libreire gd2), infatti generando solo una tabella contenente gli stessi
dati del grafico i tempi sono gli stessi.
Stiamo pensando a possibili soluzioni (ne vediamo solo due):
1) cercare di ottimizzare il db (anche se a noi sembra già
ottimizzato) e quindi di sistemare i dati in modo diverso
2) creare delle strutture intermedie che conservino dei dati aggregati
in modo che tali dati risultino subito disponibili per i grafici senza
calcoli: il problema è che bisogna preoccuparsi di aggiornare questi
dati intermedi ogni qualvolta si tocca una virgola e quindi alla fine
fare gli stessi calcoli centinaia di volte (anche se sicuramente più
veloci).
Non so se il problema è chiaro. Esistono altre strategia "documentate"
per problemi di questo tipo?
Grazie
giaconet

 inaccettabile). Il problema non è legato al grafico (generato con
Dovresti postare del codice e la struttura del db per raccogliere dei  
suggerimenti.
6 minuti è decisamente troppo.
Tac
La netiquette prevede sign di al massimo quattro righe.
Purtroppo la mia sign in quattro righe non ci stà.

 per problemi di questo tipo?
Cercati tutte le info che trovi su datawarehouse e datamart (market
intelligence, data mining...)
Ciao.
Johnny T.

 dati del grafico i tempi sono gli stessi.
Le tabelle sono indicizzate?
Si possono creare diversi indici in base al tipo di query da eseguire
....
--
mm

Ok, grazie a tutti. Cerco di definire meglio il problema.
Le tabelle sono tutte di tipo MyISAM, quindi senza relazioni (e
dovrebbero essere le più veloci). Di queste tabelle oltre alle chiavi
primarie sono indicizzate tutte le chiavi di join.
Non riporto tutti i campi e non riporto il codice perché troppo lungo,
ve lo racconto.
Può darsi che qualche ottimizzazione si possa fare trasferendo
operazioni che attualmente fa l'interprete php al motore MySql.
carichi_lavoro
id_carico
id_dipendente
id_commessa
data_carico
ore_ordinarie
ore_straordinarie
trasferta
km
spese
e altre voci di questo genere
dipendenti
id_dipendente
nome
cognome
ecc
dipendenti_paghe_orarie
id_paga
id_dipendente
periodo
valore
percentuali
id_situazione
periodo
tfr
inail
inps
irap
tredicesima
ecc.
la tabella che contiene più dati è ovviamente carichi_lavoro, per
ogni dipendente contiene n record per ogni giorno lavorativo, inoltre
ci sono molte altre voci oltre a quelle che ho scritto.
Il grafico deve riportare il costo aziendale per questi carichi che si
ottiene in questo modo: si matchano le ore lavorative con la paga
oraria del dipendente (la paga oraria subisce modifiche nel tempo,
quindi va considerata quella contestuale alla data del carico), poi si
applicano tutta una serie di maggiorazioni secondo le indicazioni
presenti nella tabelle percentuali (anche qui il calcolo va
contestualizzato alla riga di "percentuali" idonea per la data del
carico).
Il calcolo funziona perfettamente ma nel worst case (una commessa di
circa 2 anni) ci mette davvero una vita (i famosi 6 minuti).
Il problema potrebbe risiedere nel fatto che, come dicevo, non sono
riuscito a fare un'unica query, ma ci sono delle query annidate.
In pratica scorro il recordset sui carichi e a seconda della data del
carico faccio un'altra query (e quindi una per ogni carico del
recordset) sulle paghe orarie e sulle percentuali per ricavarmi la paga
e le percentuali giuste. Il campo periodo della tabella paghe e della
tabella percentuali non è altro che la data a partire dalla quale vale
quel record; la validità è fino al campo periodo del record
successivo o fino ad oggi se si tratta dell'ultimo record.
Sperando che si sia capito qualcosa :-(
Grazie ancora per l'interessamento
giaconet



Primo. E' ottimo normalizzare il database, però in questo caso mi pare  
eccessivo il fatto di non memorizzare per ogni carico anche il costo. Non  
sono voci (almeno in linea di massima) che subiscono cambiamenti  
retroattivi, quindi una volta che il carico di lavoro è completato,  
potresti salvare tranquillamente il costo totale sulla tabella dei carichi.
Come secondo dato, sicuramente trasferire la procedura in mysql accelera  
il lavoro, ma tieni presente che neanche mysql regge all'infinito e per  
compiti complessi potrebbe decidere di costruirsi una tabella temporanea  
(il che ti rallenterebbe, ovviamente).
Come terza cosa (nel caso volessi applicare il primo punto):  
nell'algoritmo di lettura di percentuali e paghe puoi memorizzare le paghe  
già lette in un array/oggetto, di modo da evitare query ridondanti (che  
immagino siano parecchie) (se tiri fuori i record in ordine di  
dipendente/percentuale potresti ottimizzare ulteriormente la cosa).
Inoltre dovresti ragionare sulle cifre:
quanti record hanno le singole tabelle?
Se le tabelle collegate non hanno troppi record potresti saltare il  
discorso (3) a piè pari e leggere direttamente tutti i record che ti  
interessano dalle tabelle collegate, tenendoteli in memoria.
(php di default ti dà 8 mega di memoria, potresti tranquillamente decidere  
di aumentare questo limite nel caso non basti).
In questo caso avresti:
1) Query dipendenti
2) Query Paghe Orarie
3) Query Percentuali
4) Query carichi di lavoro
4 Query non sono molte, in fondo.
Tac
-- 



Hai ragione, era uno dei primi dati da postare. Allora la tabella
carichi ha in media 40 (carichi al mese, perchè in un giorno un
operaio lavora anche su più commesse) x 11 (mesi, agosto non si
lavora) x 2 (anni) x 300 (dipendenti) = 264mila record, più o meno. Il
tasso di incremento è ovviamente 40 x 300 = 12mila record al mese,
più o meno.
Grazie per i consigli
bye
giaconet

 più o meno.
Mi interessava piu' che altro numero e tasso d'incremento delle tabelle  
collegate.
Detto questo, propenderei per i campi di caching, direi che a conti fatti  
è la soluzione migliore.
L'unica accortezza è, ovviamente, codice (php) ben strutturato onde  
evitare calcoli sballati e disallineamenti.
