Newsgroup: it.comp.lang.perl
Titolo: DBI: Conviene essere 'preparati' a tutto?

Una domanda seria, dopo tante risposte.
Sto rivedendo il programma perl che ho scritto insieme ad nostro studente per
gestire un database bibliografico tramite MySQL (in particolare uso
DBI+DBD::mysql).
Il programma e' usato principalmente tramite CGI, ma alcune funzioni
(soprattutto per l'inserimento) sono strutturate per essere richiamate anche
da alcuni programmi non CGI che uso per caricare i dati in massa (provate
voi a inserire 700 record tramite un form HTML!!!!).
Rivedendo il codice che mi ero inventato un anno fa, mi e' venuto un dubbio
'strutturale' che provvedo ad esprimere.
Sono previste query su diverse combinazioni di campi, e il database
e' strutturato, forse in maniera un po' naif, tramite una tabella
principale, due tabelle secondarie, alcune accessorie, e, soprattutto, due 
tabelle di relazione tra la principale, e le secondarie, trattandosi di
relazioni una a molti. Ma alla fine, di fatto, la struttura del database non
interessa, se non in relazione al fatto che le query sono particolarmente
incasinate e preferisco fare tante subquery piuttosto che forgiare SELECT
ipercomplicate.
Siccome le query sono tante, e di tipo diverso, a seconda del
fatto che stia facendo ricerca o inserimento, o che stia cercando
all'interno di un campo/tabella particolare, l'approccio che avevo scelto a
suo tempo era di preparare in anticipo tutte le query necessarie,
inserendole in un hash, ovvero eseguire all'inizio di tutto delle funzioni
piene di 
  $prepared{NOME_QUERY} = $dbh->prepare("SELECT * FROM tabella 
                                        WHERE (id=?)");
con tutte le stringhe di SELECT e condizioni WHERE necessarie alle mie
ricerche. 
Di fatto ho cinque blocchi di prepare() per la ricerca, l'inserimento, la
cancellazione, il lock in lettura e il lock in scrittura. Quando mi connetto
al database in sola lettura, inizializzo solo i blocchi di ricerca e lock in
lettura, altrimenti li inizializzo tutti.
A questo punto il mio dubbio e': ma per un CGI mi conviene? Preparare tutto
in anticipo e' certamente conveniente per l'inserimento 'bulk', ma mi serve
in un programma eseguito sempre una sola volta, dall'inizio?
L'approccio attuale e' quello di un cacheing totale delle query preparate. 
Ma non e' che in un CGI mi conviene piu' un caching selettivo, preparando e
memorizzando le query man mano che incontro, per ritrovarmi alla fine ad
aver preparato solo le query che ho effettivamente usato?
Qualcuno ha piu' esperienza di me in proposito, ad esempio ha rilevato
differenze nelle prestazioni a seconda dell'approccio seguito? 
Tra l'altro io uso molto i placeholder e, per quel che ne so, MySQL non li
supporta direttamente e sono di fatto forniti da qualche meccanismo di
DBD::mysql. A questo punto, ci guadagno ancora con tutte quelle
preparazioni, fatte in quel modo?
Tra l'altro, il mio collega insiste perche' io renda 'pubblico' il database,
per cui il risultato della re-ingegnerizzione attuale potrebbe prima o poi
diventare un programma disponibile. In effetti, devo solo sistemare la
mappatura 'query utente' <-> 'query SQL' (semplice) e il Javascript della 
parte di gestione dei form (piu' complicato).
Rimango in attesa di suggerimenti a proposito.
Maurizio
-- 
Maurizio M. Munafo' / 
mmmu...@netscape.net
"Consider Phlebas, who was once handsome and tall as you" (T.S.Eliot)


Il fatto che anche tu faccia una domanda ti rende un po' piu' umano: ero
oramai convinto che tu fossi un marziano arrivato non si sa come tra noi al
solo scopo di risolvere tutti i nostri problemi :)
Io preparo sempre le select solo prima di eseguirle, ma il mio caso e'
diverso perche' le mie select sono sempre molto diverse le une dalle altre,
tanto che ho rinunciato all'uso dei placeholders per costruire dinamicamente
addirittura l'intera clausola where (ogni volta).
A dire il vero non mi sono posto neanche il problema se questo fosse un bene
o un male.
Secondo me non fa tanta differenza, almeno finche' si usano DBMS che non
fanno conti complicatissimi alla prepare (come credo MySQL, non so
esattamante cosa faccia MySQL alla prepare). Non ho tuttavia esperienze
comparative di valutazione di performance da fornirti.
In definitiva, non ti sono stato di grande aiuto, lo so. Ero solo contento
del fatto che hai fatto una domanda ed ho voluto rispondere con quel poco
che sapevo, grazie
Maurizio Coppari

 che sapevo, grazie
Beh, grazie :)
Per la cronaca, sono ancora interessato alla risposta, anche se ho deciso di
accantonare il problema, al momento. Le mie routine di ricerca seminuove
vanno che e' una meraviglia! :)


 wrote:
: L'approccio attuale e' quello di un cacheing totale delle query preparate. 
: Ma non e' che in un CGI mi conviene piu' un caching selettivo, preparando e
: memorizzando le query man mano che incontro, per ritrovarmi alla fine ad
: aver preparato solo le query che ho effettivamente usato?
Non ho una grossa esperienza con MySQL, quindi non posso darti consigli
specifici, ma puoi sempre provare a far partire il tuo programma da
linea di comando, tanto usi il modulo CGI, quindi puoi passargli gli
argomenti su stdin, e temporizzare il tutto con time(1).
: Ma alla fine, di fatto, la struttura del database non
: interessa, se non in relazione al fatto che le query sono particolarmente
: incasinate e preferisco fare tante subquery piuttosto che forgiare SELECT
: ipercomplicate.
Mmm, un DB serio (ma non so se MySQL lo sia) e` in grado di ottimizzare
le query piu` complicate. Ci si aspetta che l'ottimizzatore sia stato
studiato per anni da gruppi di analisti esperti nel settore e che sia in
grado di rimescolare i dati grezzi in maniera piu` efficiente sia in
termini di memoria occupata che di velocita` di esecuzione, di quanto
non si possa fare con un programma in Perl.
...e in caso di query che sputano fuori grossi quantitativi di dati,
anche meglio di quanto il sistema operativo possa fare con la sua swap
partition. Considera che i DB come Oracle o Sybase non si appoggiano al
file system fornito dal sistema operativo, perche` troppo generico, ma
ne gestiscono uno ad hoc all'interno del file (o raw partition dove
possibile) in cui installano le loro tabelle.
Tutto questo per dire che magari faresti meglio a fidarti
dell'ottimizzatore di MySQL (previo benchmark magari, se hai tempo
sufficiente per fare queste prove).
-- 
Nando Santagata: Telemastica & infornatica
Key fingerprint = C2 D9 C0 8E D5 B7 04 97  AF E8 3F 3E AF 4E 7F 9E
finger nandos (at) mail (dot) ipers (dot) net   for my PGP public key
Home: 
http://www.ipers.net/~nandos

 wrote:
: Per la cronaca, sono ancora interessato alla risposta, anche se ho deciso di
: accantonare il problema, al momento. Le mie routine di ricerca seminuove
: vanno che e' una meraviglia! :)
Un'idea stamba e non verificata: se mettessi tutto sotto mod_perl e
usassi il modulo per cache-are le connessioni al DB ed usassi dei
descrittori di statement SQL in variabili non lessicali, probabilmente
sarebbe sufficiente fare la compilazione della query una sola volta
nella vita del server.
Bhe`, non e` esattamente portabile :-)


 Bhe`, non e` esattamente portabile :-)
Dipende da cosa intendi per portabile.


 wrote:
:> Bhe`, non e` esattamente portabile :-)
: Dipende da cosa intendi per portabile.
Che ha una serie di prerequisiti (Apache, Perl, mod_perl e Apache::DBI)
che e` difficile incontrare tutti insieme per caso...
Mi riferivo al fatto che intendevi rilasciare il tuo codice, non alla
portabilita` del tutto su varie piattaforme.


 wrote:
: Il problema ora sono gli utenti che spuntano sempre con richieste tipo 
: "ma non e' che e' possibile mettere i risultati della ricerca DIRETTAMENTE
: nella mia pagina" o altri strani requisiti. Ad esempio, non ti aspetteresti
Hai mai provato CIPP e Apache::CIPP?
Li ho appena usati per un lavoro piuttosto grosso e devo dire che
funzionano abbastanza bene.


 portabilita` del tutto su varie piattaforme.
Portabilita' di un codice che dipende dal database mySQL che c'e' sotto e
che deve avere ESATTAMENTE gli stessi campi? Non mi sembra un problema :)
L'idea del mio collega (cui io sono tendenzialmente refrattario) e' che sia
un blocco unico con il database: se vi installate mySQL e create le tabelle 
con questo formato (che vi forniamo), potete usare il nostro programma per 
gestirvelo. Per cui e' un programma che serve solo e solamente per gestire
un database di pubblicazioni scientifiche COME VOGLIO IO, che ho scelto la
struttura, i campi e le categorie. Ovviamente se uno conosce Perl e MySQL
puo' adattare il programma alle proprie necessita' senza troppo problemi.
Maurizio


 funzionano abbastanza bene.
Provero' a cercare. Per ora mi sono arrangiato aggiungendo una modalita' SSI
al mio script di interfaccia, richiedendo all'utente solo due parametri e
fornendo io tutti gli altri prima di chiamare lo script principale.
Lo so che e' lento, ma dato l'uso per ora non e' un problema.
