Database Tuning - Tesi Roberto Mirabella

UNIVERSITÀ DEGLI STUDI DI CATANIA
FACOLTÀ DI SCIENZE MATEMATICHE FISICHE E NATURALI
CORSO DI LAUREA DI 1° LIVELLO IN INFORMATICA
ROBERTO MIRABELLA
DATABASE TUNING
Tesi di Laurea
Relatrice:
Chiar.ma Prof.ssa ROSALBA GIUGNO
ANNO ACCADEMICO 2010 - 2011
Ai miei genitori.
2
SOMMARIO
PREMESSA ...................................................................................... 6
1. DATABASE E DATABASE TUNING .................................... 9
1.1. Cenni storici sui database. ............................................................ 9
1.2. I database ai giorni nostri. .......................................................... 11
1.3. Che cos‟è il database tuning? ..................................................... 13
1.4. I principi fondamentali ............................................................... 14
1.5. Livelli di intervento .................................................................... 18
2. TUNING DEL SISTEMA ....................................................... 24
2.1. Tuning dell‟Hardware ................................................................ 24
2.1.1.
Tuning del sottosistema di archiviazione ................................. 25
2.1.2.
Modifica e aggiunta di componenti Hardware ......................... 32
2.2. Tuning del Sistema Operativo .................................................... 36
2.2.1.
Gestione dei Threads ................................................................ 37
2.2.2.
Database buffer ........................................................................ 41
2.2.3.
File System ............................................................................... 43
2.3. Tuning del DBMS ...................................................................... 45
2.3.1.
Locking Tuning ........................................................................ 45
2.3.2.
Logging Tuning ....................................................................... 48
3
2.4. Tuning Applicativo ..................................................................... 50
2.4.1.
Modello Client-Server .............................................................. 51
2.4.2.
Tuning delle Interfacce Applicative ......................................... 52
3. TUNING DEL DATABASE ................................................... 53
3.1. Tuning a Livello Logico ............................................................. 53
3.1.1.
Normalizzazione....................................................................... 55
3.1.2.
Denormalizzazione ................................................................... 61
3.1.3.
Overnormalizzazione ............................................................... 63
3.2. Tuning a Livello Fisico .............................................................. 64
3.2.1.
Tuning degli indici ................................................................... 64
3.2.2.
Tuning delle query ................................................................... 74
4. APPLICAZIONE PRATICA DEL TUNING ......................... 78
4.1. I Benchmark ............................................................................... 78
4.2. Sistemi di Archiviazione MySQL .............................................. 80
4.2.1.
MyISAM .................................................................................. 80
4.2.2.
InnoDB ..................................................................................... 80
4.3. Implementazione ........................................................................ 81
4.4. I Risultati: Analisi Sintetica ....................................................... 83
4.4.1.
Query per secondo .................................................................... 84
4.4.2.
Byte per secondo ...................................................................... 85
4.4.3.
Tempi di risposta minimi ......................................................... 86
4.4.4.
Tempi di risposta massimi ....................................................... 88
4
4.5. I risultati: Analisi Analitica ........................................................ 90
4.5.1.
Tempi di esecuzione New-Order ............................................. 90
4.5.2.
Tempi di esecuzione Payment .................................................. 92
4.5.3.
Tempi di esecuzione Delivery .................................................. 94
4.5.4.
Tempi di esecuzione Order-Status ........................................... 96
4.5.5.
Tempi di esecuzione Stock-Level ............................................ 98
4.6. Conclusioni ............................................................................... 100
BIBLIOGRAFIA .......................................................................... 102
5
PREMESSA
Al giorno d‟oggi, con l‟evoluzione sempre più veloce e prodigiosa dei mezzi
di comunicazione, la società si è abituata ad avere accesso, in pochi secondi,
quando vuole, alle informazioni che vuole. Basti pensare ai sistemi di gestione
della sanità, alle banche dati delle forze dell‟ordine, alla gestione dei mezzi di
trasporto o anche, a livello più piccolo, alla gestione delle attività di
un‟azienda o, perché no, ai social network, per capire come tutti gli aspetti
importanti della vita di ciascuno di noi siano condizionati da questa premessa.
Se nel piccolo, garantire velocità e portabilità delle informazioni è abbastanza
semplice e chiunque, con un minimo di conoscenze informatiche, è ormai in
grado di creare un database in Access che soddisfi tali esigenze, quando,
invece, le informazioni da gestire diventano milioni o più, ottenere lo stesso
risultato non è altrettanto scontato. Se un ritardo più o meno lungo
nell‟accesso all‟informazione può essere in certi casi
tollerato, come ad
esempio nella ricerca di un libro in una biblioteca, in altri casi, come
l‟elaborazione in tempo reale di dati scientifici, la velocità diventa di
fondamentale importanza. Proprio per venire incontro a queste necessità nasce
il Database Tuning.
Per la stesura di questo lavoro, inizialmente è stata condotta una ricerca di
articoli, testi, linee guida e schematizzazioni, reperiti attraverso internet,
6
insieme alla revisione di letteratura cartacea disponibile. Successivamente, è
stata effettuata una valutazione del materiale raccolto e, infine, si è passati alla
stesura della tesi.
Cercando di non trascurare nessun aspetto relativo a questa tematica
l‟argomento è stato suddiviso in quattro macroaree.
Nella prima, viene introdotto l‟argomento partendo da una serie di accenni
storici sull‟evoluzione dei database così da evidenziare come sono nate le
esigenze degli utenti che il tuning cerca di soddisfare. Poi è stata data una
definizione formale del database tuning e si è entrati nel merito di quali sono i
principi fondamentali a cui gli amministratori devono attenersi. Per finire,
vista la complessità dell‟argomento, si è cercato di schematizzare la trattazione
suddividendola in vari livelli di intervento.
La seconda macroarea ha come tema principale la trattazione analitica di tutti i
livelli di intervento non legati a operazioni dirette sul database, ovvero a tutte
quelle scelte che riguardano l‟hardware, il sistema operativo, il DBMS e i
programmi applicativi del sistema.
La terza macroarea riguarda invece tutti i livelli le cui operazioni modificano
direttamente il database, concentrandosi soprattutto sui concetti di
normalizzazione, denormalizzazione, gestione degli indici e ottimizzazione
delle query.
7
La quarta macroarea infine è il risultato della realizzazione di un esperimento
di tuning pratico realizzato in MySQL. Dopo una breve introduzione vengono
presentati i dati raccolti, le loro rielaborazioni, e le conclusioni da essi derivate
a conferma di quanto esposto nell‟intero elaborato.
8
1. DATABASE E DATABASE TUNING
Prima di iniziare a parlare delle tecniche di tuning è importante soffermarsi un
attimo a riflettere sul passato per capire quale è stata, fino ad oggi,
l‟evoluzione dei database e cosa ha portato alla nascita del database tuning.
Molte sono le domande che possiamo farci in proposito. Come erano
strutturati i primi database? Chi ha ideato i modelli su cui si basa oggi la
progettazione di una base di dati? Come si sono evolute le esigenze degli
utenti negli anni? In che modo interviene il tuning per ottimizzare le
prestazioni di un database?
1.1. CENNI STORICI SUI DATABASE.
La nascita del concetto di database o base di dati risale a molti anni prima
dell‟avvento dei calcolatori, quando le informazioni venivano scritte e
memorizzate in forma cartacea. Archivi, schedari, rubriche possono
tranquillamente essere considerate le antenate delle moderne basi di dati.
Con il passare degli anni e con l‟evolversi della tecnologia, il termine
database ha assunto un significato sempre più legato all‟aspetto
informatico. Le prime forme di database elettronici risalgono agli anni
Sessanta, quando il miglioramento dei calcolatori permise la creazione di
una serie di “raccolte dati” destinate a varie applicazioni. Negli anni
9
seguenti, gli informatici si concentrarono a perfezionare e ottimizzare i
programmi di gestione e non apportarono nessun miglioramento alla
struttura usata per organizzarli.
Nel 1968 l‟IBM sviluppò il primo ambiente di gestione soprannominato
“IMS”. I dati erano strutturati in forma gerarchica. Al caricamento veniva
visualizzato il primo dato e un collegamento al dato successivo. Per
selezionare un gruppo di informazioni o trovarne una in particolare,
l‟utente doveva scorrere l‟intero archivio in sequenza fino a trovare
l‟informazione desiderata. Non esistevano query di ricerca. Anche le query
più semplici richiedevano, per le risorse dell‟epoca, notevoli quantità di
memoria e di tempo.
Qualche anno dopo, nel 1971, per opera di Charles W. Bachman, fu
lanciato sul mercato un altro standard, che prese il nome di "Approccio
Codasyl”. L‟Approccio Codasyl supportava una struttura dati a rete ma
per il resto era molto simile all‟IMS. I database di entrambi gli standard
furono classificati, per il loro funzionamento, con il nome di database
navigazionali.
La vera idea innovativa, nacque solo più tardi, nel 1973. Un dipendente
dell‟IBM, Edgar F. Codd durante il suo lavoro di ricerca per il prototipo
del nascente harddisk, si rese conto che l‟approccio Codasyl era
inefficiente se applicato alla nuova tecnologia. Codd capì che per
migliorare le prestazioni era necessario concentrarsi non solo sui
10
programmi di gestione ma anche, soprattutto, sull‟organizzazione dei dati
da gestire. Formulò diverse teorie, scrisse trattati, distinse la struttura
logica del database dalla sua realizzazione fisica, definì le regole per la
creazione del Modello Relazionale e per la sua normalizzazione. In pratica
gettò le basi per la nascita dei database relazionali e del linguaggio SQL.
Le sue idee ebbero un esito positivo nella comunità scientifica: non solo
l‟IBM ma anche diverse università italiane, puntarono su di lui e crearono
il “System R”, predisposto per la gestione dei dati in una monotabella e
successivamente “SQL/DS”, “DB2”, “INGRES” ed un precursore di
Oracle. Questi nuovi sistemi permisero per la prima volta di suddividere i
dati in tabelle separate.
L‟idea di Codd fu talmente buona che, tre anni dopo, Peter Chen la
perfezionò proponendo il suo Modello E/R (Entity-Relationship), valido
ancora oggi. Questo modello prevede tre livelli di progettazione dei
database (a differenza dei due definiti da Codd): il livello concettuale, il
livello logico e il livello fisico. Chen introdusse anche il concetto di Entità
(oggetti astratti o concreti) e Relazioni (legami tra le entità).
1.2. I DATABASE AI GIORNI NOSTRI.
Dagli anni Ottanta in poi, con la diffusione dei personal computer e la
standardizzazione del linguaggio SQL, i programmi di gestione dei
11
database relazionali (RDBMS) sono proliferati: Oracle, MySql, Microsoft
Access, DB2 ne sono solo alcuni esempi.
L‟uso recente di internet ha poi contribuito a centrare l‟attenzione della
comunità su nuove problematiche. Il modello di Chen è stato, negli anni
Novanta, affiancato dal “Modello Client/Server” che permette, non solo
una migliore ripartizione delle funzioni tra database e applicativo ma anche
la possibilità di gestire il sistema attraverso la rete. L‟uso dei database in
remoto, prima con le pagine ASP, poi, soprattutto, con il linguaggio PHP,
ha consentito ai dipendenti delle aziende di accedere a informazioni prima
inaccessibili ed ha anche permesso alle persone comuni di poter usufruire
di servizi prima inesistenti. Si potrebbero citare tantissimi esempi:
l‟accesso ai dati di una filiale dagli uffici della sede centrale di un‟azienda,
la creazione di siti e-commerce, i sistemi di pagamento online, i social
network, i forum di discussione, i guestbook personali. Dietro ognuna di
queste cose c‟è un server che interroga una base di dati e soddisfa le
richieste dell‟utente.
Quelli che erano i requisiti fondamentali di un database (l‟affidabilità, la
struttura semplice, la gestione di dati alfanumerici, le transazioni brevi, la
condivisione e la gestione delle query più complesse) si sono rivelati, in
diversi campi di applicazione, insufficienti.
Ispirati dall‟evoluzione delle tecniche di programmazione, gli informatici
hanno, quindi, ideato un nuovo modo di concepire le basi di dati: il
12
modello a oggetti. Questo nuovo tipo di database, ancora oggi poco
diffuso, permette agli utenti di creare e gestire direttamente non solo
informazioni alfanumeriche, ma qualsiasi altro tipo di oggetto come foto,
video, brano musicale, ecc.
Durante tutto questo processo di innovazione, gli utenti si sono
velocemente abituati ad avere le informazioni che vogliono in pochi
secondi, indipendentemente dalla quantità di dati che il database deve
gestire. L‟efficienza è tornata ad essere quindi il fattore di principale
importanza e di conseguenza anche il database tuning.
1.3. CHE COS’È IL DATABASE TUNING?
“Database tuning is the activity of making a database application run more
quickly. „More quickly‟ usually means higher throughput though it may mean
lower response time for some applications. To make a system run more quickly,
the database tuner may have to change the way applications are constructed, the
data structures and parameters of a database system, the configuration of the
operating system, or the hardware” (Shasha/Bonnet 2004, XIX).
Con database tuning si intende, come sopracitato, una serie di operazioni
pianificate a medio o lungo termine, con le quali si cerca di migliorare al
massimo le prestazioni di un database in un ben predefinito ambiente di
lavoro.
13
Ciò significa che, per ottenere le massime prestazioni, non basta operare sul
database, ma bisogna andare ad agire anche sul DBMS, sul sistema
operativo e sull‟hardware in uso.
Molte persone, condizionate dal significato inglese di tuning, lo associano
alla semplice ottimizzazione ma, in realtà, si tratta di due concetti distinti.
L‟ottimizzazione è un‟operazione che viene svolta nella fase finale della
progettazione logica o direttamente sulla struttura fisica del database. Serve
a migliorare il suo funzionamento a prescindere dal contesto in cui dovrà
poi funzionare.
Il tuning invece è qualcosa di più. Si tratta di un insieme di attività che
coprono l‟intera vita del database, dallo studio del contesto iniziale
all‟attività costante di monitoraggio dei flussi di dati. Le migliorie apportate
al database tramite il tuning non risultano sempre efficaci se applicate in
altri contesti.
1.4. I PRINCIPI FONDAMENTALI
Proprio per come è stato definito, studiare il tuning diventa estremamente
complicato. Non ci sono soluzioni decontestualizzate che producono
risultati ottimali, stabilire delle dettagliate regole di comportamento per
situazioni predefinite è difficile. L‟efficacia di ogni scelta va valutata caso
per caso. Per questo motivo, ciascun amministratore deve sempre tenere
presente cinque principi cardine e agire di conseguenza.
14
Il primo principio è stato riassunto, con la frase: “pensare globalmente e
agire a livello locale (Trad. Shasha/Bonnet 2004, 2)”. Ciò significa che, un
buon amministratore, pur avendo ben presente la situazione complessiva del
database, per fare un buon tuning deve essere in grado di individuare i
piccoli cambiamenti necessari alla base di dati per ottenere grossi
miglioramenti prestazionali. Un intervento che stravolge la natura del
database, andando a riprogrammare anche parte degli aspetti prima
funzionanti, non è considerato un buon tuning. Tale intervento, non solo
vanificherebbe lo studio del problema ma ne produrrebbe di nuovi e
imprevisti.
Il tipico problema con cui si ha a che fare quando si lavora con i database e,
in generale con l‟informatica, è quello soprannominato bottleneck o “collo
di bottiglia”. In pratica, qualsiasi progetto strutturato in più componenti è
considerato efficiente nella misura in cui lo è il suo componente peggiore.
Nel database non serve cambiare tutto, ma solo migliorare o sostituire i
componenti difettosi.
Il secondo principio, “Il partizionamento per risolvere i colli di bottiglia
(Trad. Shasha/Bonnet 2004, 2)”, ci dà una guida su come agire in queste
particolari situazioni.
Se una componente è satura, si possono scegliere due strade diverse: o si
suddividono le informazioni smistandole in più risorse così da riuscire a
15
gestire tutte le partizioni senza che nessuna crei sovraccarico, o si
suddividono le informazioni frazionando la loro gestione nel tempo.
Prima di procedere al partizionamento è sempre bene provare l‟alternativa
più semplice: controllare la struttura e il codice del componente difettoso ed
eseguire, se possibile, le opportune correzioni per eliminare alla radice il
collo di bottiglia. Ad esempio, se abbiamo una query che non usa gli indici
o li usa male è sempre meglio riscrivere la query che partizionare la tabella
a cui fa riferimento.
Il partizionamento, infatti, è una di quelle scelte che non sempre produce un
aumento di prestazioni. Va valutato il singolo caso. Potrebbe succedere che
i costi accessori dovuti alla gestione delle partizioni siano maggiori del
costo, in termini di prestazioni, del bottleneck.
Il terzo principio fondamentale da seguire riguarda un aspetto tipicamente
umano. Davanti ad un obiettivo da raggiungere, il primo passo è sempre il
più ‘costoso’. Forse consapevolmente o forse inconsciamente, l‟essere
umano trasmette questa caratteristica anche alle sue creazioni. Un esempio
esaustivo potrebbe essere il processo produttivo di un‟azienda di manufatti
in vetro. La realizzazione del primo manufatto, con l‟accensione iniziale del
forno e il raggiungimento della temperatura adatta, richiede un costo di
risorse e di tempo molto più alto rispetto alla produzione dei manufatti
successivi.
16
Gli elaboratori non fanno eccezione. Si pensi al processo di bootstrap, alla
lettura di un‟informazione dal disco o anche all‟attivazione di una
connessione di rete. La prima fase è sempre la più costosa in termini di
risorse. Lo stesso principio vale per i database.
E ancora, l‟amministratore deve “dare al server quello che è del server.
(Trad. Shasha/Bonnet 2004, 2)”.
Una buona progettazione tiene accuratamente distinto il carico di lavoro del
database (il server), da quello che invece spetta al programma applicativo
(il client).
Prendiamo un‟interfaccia grafica che visualizza un dato inserito nella base
di dati e permette all‟utente di modificarlo e salvarlo. Caricare il server
delle funzioni di ricerca, visualizzazione, interazione e salvataggio
comporterebbe un inutile sovraccarico. La soluzione più giusta sarebbe
invece quella di affidare la visualizzazione e l‟interazione con l‟utente
all‟applicativo e coinvolgere il database solo per le restanti operazioni.
L‟ultimo principio, che un amministratore di database deve tenere
costantemente presente è che “deve essere pronto ad accettare dei
compromessi (Trad. Shasha/Bonnet 2004, 2)”.
Non esiste una soluzione efficace senza controindicazioni. Se progettiamo
un database che fa grande ricorso agli indici per migliorare l‟accesso alle
sue tabelle, dovremo tener conto che ogni indice richiederà un costo
aggiuntivo sia al processore sia alla memoria di buffer e fisica.
17
Trovare il giusto equilibrio non è mai facile ma è proprio il compito che si
ci prefigge con il tuning del database.
1.5. LIVELLI DI INTERVENTO
Le operazioni di ottimizzazione compiute da un amministratore che opera
tuning non solo devono tener conto di conoscenze che vanno oltre lo studio
dei database, abbracciando altri temi come la gestione dei buffer di
memoria o il sistema di archiviazione dei dati sul supporto fisico, ma
coinvolgono l‟intero sistema.
Cercando di organizzare e semplificare i vari aspetti coinvolti, è possibile
definire i seguenti livelli di intervento:
 Hardware;
 Sistema Operativo;
 DBMS;
 Applicativo
 Modello Logico del Database
 Modello Fisico del Database
Saper scomporre il problema e individuare i giusti livelli di intervento è
fondamentale se si vogliono ottenere dei miglioramenti reali e a lungo
termine.
Un intervento a livello hardware, consiste nel compiere tutte quelle scelte
che prevedono la modifica dei componenti fisici del sistema.
18
Principalmente tali modifiche riguardano l‟aggiornamento del processore,
l‟aggiunta di memoria principale e secondaria nonché l‟ottimizzazione dei
bus di sistema. La difficoltà nell‟operare le scelte di tuning su questo
livello consistono nella ricerca del miglior compromesso tra costo
hardware ed efficienza.
Per quanto riguarda il livello del Sistema Operativo, sarebbe necessario
fare una lunga premessa specificando, per ogni Sistema Operativo, i
relativi parametri di configurazione inerenti le procedure di tuning.
Premesso però che non è mai possibile eliminare tutti i colli di bottiglia
presenti nel sistema, alcuni strettamente legati alle limitazioni hardware, è
necessario sottolineare che proprio questo numero di questi parametri può
a sua volta rappresentare un bottleneck.
Considerando tale argomento meritevole di un più attento approfondimento
e impossibile da concentrare in poche righe, in questa trattazione si è
preferito affrontarlo con le dovute astrazioni. Si parlerà quindi di gestione
ottimizzata dei Threads, dell‟organizzazione del buffer di database e del
file system.
Intervenire con operazioni di tuning significa ottimizzare il software che si
occupa della gestione del database: il DBMS. Tali interventi vertono
principalmente su due aspetti della gestione: i locking delle transazioni e
l‟ottimizzazione del sistema di logging.
19
Altro aspetto importante è la configurazione dei programmi posti tra gli
utenti finali e il DBMS. Considerando che gli applicativi di norma vengono
eseguiti su macchine diverse da quelle che gestiscono il database server,
non solo sarà importante ottimizzare le interfacce eseguite dai client ma
anche la rete di connessione tra le macchine. Demandati i problemi inerenti
la scelta del giusto protocollo, dei giusti canali di comunicazione,
dell‟instradamento migliore dei pacchetti, dell‟ottimizzare degli algoritmi
che gestiscono le collisioni, ecc. ai livelli del modello ISO/OSI o TCP/IP
relativi alle reti, si ci concentrerà, in questo elaborato, sulle tematiche più
legate ai database quali i vantaggi e gli svantaggi dell‟utilizzo del modello
Client/Server inteso come modello Applicativo/Database Server e
l‟ottimizzazione del codice dei programmi applicativi.
Iniziare il tuning del database in fase di progettazione, può rappresentare
un notevole vantaggio per il sistema. Partire da un modello logico
ottimizzato ed efficiente significa creare un database predisposto ad
affrontare le situazioni critiche che potranno verificarsi durante il suo
funzionamento e persino evitarle.
Gli interventi sul database possono essere effettuati sui diversi modelli di
progettazione. Quando si interviene sul modello logico, in genere, si parla
di normalizzazione (ottimizzazione dei dati),
(creazione
di
ridondanza
per
20
migliorarementi
denormalizzazione
funzionali)
e
overnormalizzazione. (creazione di ridondanza per snellire le strutture
dati).
Gli interventi di questo tipo sono consigliati solo durante la fase di
progettazione anche se, l‟amministratore, può naturalmente ritenere farlo
anche successivamente. In questi casi deve però tenere conto che essendo
la struttura dati già funzionante, operare modifiche al livello logico
comporta dei costi aggiuntivi e alto rischio di perdita d‟integrità del
database.
Pratica più comune vuole, che il tuning si concentri sul modello fisico del
database, ovvero su interventi al codice SQL delle query a alle strutture di
database già funzionanti. Si può intervenire sul modello fisico in tanti
modi:
a) Attraverso l‟utilizzo di strutture distinte per la memorizzazione dei
dati;
b) Con l‟uso dei raw devices (se il database opera su sistemi UNIX);
c) Con l‟aggiunta di indici e informazioni temporanee alle tabelle;
d) Attraverso la valutazione della frequenza d‟accesso delle singole
strutture;
e) Attraverso il controllo e l‟eliminazione di indici inutili o inutilizzati;
f) Attraverso il controllo delle colonne degli indici affinché
mantengano dimensioni contenute;
21
g) Attraverso il controllo della quantità di dati di ogni tabella e, se
necessario, il partizionamento.
Ottimizzare il linguaggio SQL non è per niente facile. Una grossa parte di
bottleneck presenti nel sistema spesso è legata ad una programmazione
SQL superficiale e non ottimizzata. Ecco una veloce panoramica delle
situazioni da valutare e che si presentano più frequentemente ad un
amministratore:
a) l‟esistenza di selezioni generiche come “SELECT * FROM ..." in
quanto SQL impiega ulteriori risorse per decodificare il significato
dell‟ „*‟ in base alle tabelle inserite nel „FROM‟;
b) il mancato uso di indici nelle query che coinvolgono una notevole
quantità di dati, la presenza di indici disattivati di importanza
rilevante o l‟uso di indici non opportuni;
c) l‟ordine delle tabelle e delle condizioni di selettività nelle query;
d) l‟uso di elaborazioni statistiche mediante cicli al posto di sfruttare
le funzioni di gruppo standard;
e) l‟uso dei valori null e la loro corretta gestione;
f) la presenza e l‟efficacia delle selezioni annidate;
g) la presenza di operazioni che richiedano grandi quantità di memoria
(ad esempio ORDER BY, DISTINCT e GROUP BY in tabelle
molto voluminose);
22
h) la presenza, in generale, di codici la cui esecuzione prevede lunghe
transazioni.
In generale, bisogna comunque tenere presente che, la suddivisione a
livelli è una schematizzazione logica personale che è volta esclusivamente
a dare un ordine all‟esposizione di concetti che sono profondamente
interconnessi tra loro. Stabilire, pertanto, a quale livello appartenga una
specifica operazione, non è sempre facile ai fini del tuning vero e proprio.
23
2. TUNING DEL SISTEMA
Aver visto cos‟è il Database Tuning e quali sono i principi
fondamentali su cui esso si basa non basta se si vuole operare
concretamente tuning. Nei paragrafi seguenti vengono esposte,
sinteticamente, le nozioni di tuning fondamentali relative al livello
hardware, del Sistema Operativo, del DBMS e dei programmi
applicativi.
2.1. TUNING DELL’HARDWARE
La prima cosa che viene in mente, quando il funzionamento del
sistema sembra rallentato e poco efficiente, è di intervenire a livello
hardware per aumentare le risorse disponibili. Premettendo che non
sempre un intervento del genere comporta un effettivo miglioramento
di prestazioni, è evidente che la scelta del componente del sistema su
cui intervenire è di cruciale importanza per evitare costi inutili.
Preso ad esempio, un sistema che soffre di saturazione del buffer di
memoria, l‟acquisto e l‟aggiunta di RAM nel sistema rappresenta una
buona strategia di tuning? Supposto che il costo della RAM coincida a
15 €/Mb (costo non eccessivamente oneroso), non sappiamo se la
saturazione è effettivamente legata alla scarsa capienza di memoria o
24
alla larghezza di banda del suo bus. L‟aggiunta di RAM, mentre nel
primo caso rappresenta una buona soluzione di tuning, nel secondo
comporta un completo spreco di soldi. In realtà, un calo di prestazioni
non può essere mai attribuito esclusivamente all‟hardware. Per questo
motivo è difficile distinguere in maniera netta la necessità di tuning
sull‟hardware da quella di tuning sul software.
2.1.1. TUNING DEL SOTTOSISTEMA DI ARCHIVIAZIONE
Quando si parla di sistemi su larga scala, la gestione della memoria
secondaria viene implementata attraverso l‟uso di un array di dischi
(RAID) così da sfruttare le sue due principali caratteristiche: da un lato
il RAID crea nel sistema una certa tolleranza d‟errore, fault tollerance,
dovuta alla ridondanza dei dati introdotta nei dischi multipli; dall‟altro
aumenta il throughput del sistema perché consente l‟accesso simultaneo
a più dischi.
Un array di dischi insieme al software per configurare e gestire le
periferiche di archiviazione che lo compongono, costituiscono uno
Storage Subsystem.
Le operazioni di tuning sullo Storage Subsystem prevedono:
1. La configurazione dell‟array di dischi
2. L‟ottimizzazione della cache del controller
3. La ricerca di equilibrio nello Storage Subsystem
25
Esistono diversi livelli di RAID, ognuno con particolari vantaggi e
svantaggi. Per ottenere prestazioni ottimali, dobbiamo assicurarci, per
ogni tipo di file, di adottare il livello di RAID che soddisfi meglio le
esigenze ad esso associate.
2.1.1.1.
LIVELLI DI RAID
I livelli di RAID più importanti, ai fini del tuning, sono:
 RAID 0: che divide i dati equamente tra due o più dischi con
nessuna informazione di parità o ridondanza (Striping). Le
operazioni di I/O vengono divise in blocchi di dimensioni
uguali e apportate equamente su tutti i dischi. Per questo
l'affidabilità del sistema è uguale all'affidabilità media dei
dischi diviso il numero di dischi presenti. Se un drive si guasta,
il file system non è in grado di gestire la perdita dei dati e la
sostituzione del componente danneggiato comporta la perdita di
tutti i dati del sistema. I vantaggi sono: il costo economico di
implementazione basso, le alte prestazioni in scrittura e lettura
grazie al parallelismo delle operazioni I/O dei dischi
concatenati. Gli svantaggi sono: la scarsa affidabilità e la non
fault tolerant.
 RAID 1: che crea una copia esatta (mirror) di tutti i dati su due
o più dischi. È utile nei casi in cui mantenere la ridondanza è
più importante che usare i dischi alla loro massima capacità
26
complessiva. Il sistema ha come capacità massima quella del
disco più piccolo. Poiché ogni disco presenta la copia esatta
degli altri dischi, può essere gestito autonomamente in caso di
guasti e l'affidabilità aumenta linearmente rispetto al numero di
dischi presenti. RAID-1 incrementa allo stesso modo le
prestazioni in lettura, visto che le transazioni possono accedere
ai dati da un disco mentre gli altri sono occupati. I vantaggi
sono: l‟aumento lineare di affidabilità in base ai mirror
implementati, la fault tolerant, la velocità di lettura che dipende
dal disco più veloce. Gli svantaggi sono: l‟overhead legato ai
mirror, l‟alto costo hardware legato all‟acquisto di numerosi
dischi dedicati interamente alla ridondanza e la velocità di
scrittura che dipende sia dal disco più lento sia dal numero di
dischi collegati.
 RAID 5: una delle implementazioni più popolari in hardware e
in software, che divide i dati in blocchi e stripe e distribuisce le
informazioni di parità, per rotazione, in tutti i dischi
appartenenti al RAID. Il blocco di parità non viene considerato
durante le operazioni di lettura e viene usato solo in caso di
errore per ricostruire le parti danneggiate. Se a danneggiarsi è
un intero disco, RAID 5 permette, attraverso tutti gli altri
blocchi (di dati e di parità) il recupero integrale del contenuto
27
del disco guasto. Il sistema esterno può comunque continuare a
operare in lettura e scrittura anche se con un calo di prestazioni.
Il numero di blocchi di parità per ogni stripe è direttamente
proporzionale al valore di fault tollerance. Se un blocco di
parità per ogni stripe permette il recupero del contenuto di un
intero disco in caso di guasto, più blocchi di parità permettono
il recupero dei dati in caso di guasti simultanei di più dischi. Le
implementazioni con doppia parità sono dette anche RAID 6. I
vantaggi sono: la distribuzione dei blocchi di parità e le
operazioni di lettura più veloci. Lo svantaggio consiste nelle
operazioni di scrittura più lente dovute al calcolo del blocco di
parità.
 RAID 10: è un sistema RAID 1+0 ovvero un insieme di
RAID1 gestiti in RAID0. Poiché i dischi fisici sono organizzati
in una serie di gruppi RAID 1, il danneggiamento di un disco
all‟interno di un singolo gruppo RAID 1 non comporta nessuna
perdita di dati. In caso però tutti i dischi di un gruppo si
danneggino, anche i dati negli altri gruppi sono inutilizzabili.
Il sistema di database deve gestire tre tipi di file:
 File di Log
 File Temporanei
 File di Indici o Dati
28
Nel caso dei file di log, è consigliabile utilizzare RAID 1 perché
questa struttura garantisce fault tollerance mantenendo un alto
livello di throughput in scrittura. Se i log richiedono scritture brevi
e frequenti può essere più appropriato anche l‟uso di RAID 10.
Per i file temporanei è consigliato, invece, l‟uso di RAID 0. Il
sistema può operare in lettura e in scrittura velocemente senza che,
per la natura di questi file, l‟eventuale perdita di informazioni
influisca sulle performance del sistema.
Per i file di dati o di indici la fault tollerance è fondamentale. Le
prestazioni migliori si ottengono utilizzando RAID 5. Per questo
tipo di informazioni, infatti, la frequenza di lettura è molto più alta
rispetto a quella di scrittura e le scarse performance di RAID 5 per
questo tipo di operazioni, possono essere mascherate attraverso un
buon utilizzo della cache del controller e non influiscono
sensibilmente sul funzionamento globale.
Fig. 1: Struttura RAID0 a due dischi.
29
Fig. 2: Struttura RAID1 a due dischi
Fig. 3: Struttura RAID5 a quattro dischi
Fig. 4: Struttura RAID 1+0 a sei dischi
2.1.1.2.
CHACHE DEL CONTROLLER
L‟ottimizzazione della cache del controller si basa sui principi di
read-ahead e write-back.
Read-ahead considera che il tempo necessario a leggere un blocco
dati dipende più dal tempo impiegato dal braccio meccanico del
30
disco per raggiungerlo che dal tempo di lettura vero e proprio.
Read-ahead prova a ridurre lo spreco dovuto a questo limite
hardware implementando l‟idea di non interrompere il processo di
lettura non appena si raggiunge la fine del blocco richiesto ma di
continuare a leggere i blocchi successivi inserendoli nella memoria
cache. Se questa tecnica risulta efficace per l‟accesso sequenziale ai
dati, diventa invece inefficiente quando si tratta di accessi random.
Write-back, ipotizza invece conclusa a buon fine l‟operazione di
scrittura su disco con l‟inserimento dell‟informazione nella cache.
Spetta al controller garantire che l‟operazione vada effettivamente a
buon fine. Le eventuali saturazioni possono essere gestite attraverso
una serializzazione delle richieste e una distribuzione delle
medesime in più intervalli di tempo.
2.1.1.3.
IL TUNING DELLO STORAGE SUBSYSTEM
Premesse tutte le considerazioni esposte fino a questo momento in
materia, l‟amministratore di un sistema di database, durante il
tuning hardware deve trovare il miglior bilanciamento possibile tra
le dimensioni dello Storage Subsystem e le sue prestazioni. Per
farlo dovrà tenere presente che:
 Nonostante l‟uso dello Storage Subsystem permetta di
considerare un insieme di dischi come un unico disco dalle
prestazioni elevate, aumentare il numero dei componenti del
31
sottosistema comporta un aumento del flusso di dati legato
alla sua gestione (log e index files).
 Ogni componente avrà le sue caratteristiche hardware quali
seek time, rotational latency, cache size, ecc che vanno a
influire sulle prestazioni complessive del sottosistema.
 Il bus di interconnessione SCSI, scelto in tutti i grossi
sistemi di database perché permette l‟aggiunta e la rimozione
dei dischi a sistema funzionante, ha comunque dei limiti per
quanto riguarda la tolleranza d‟errore.
2.1.2. MODIFICA E AGGIUNTA DI COMPONENTI HARDWARE
Ci sono tre principali fattori su cui intervenire quando si parla di
aggiunta di nuovo hardware: la memoria, i dischi e i processori.
2.1.2.1.
LA MEMORIA
Aggiungere memoria al sistema, oltre a essere l‟operazione, a
livello hardware più economica, comporta un aumento del buffer
pool1 e delle prestazioni di sistema. La memoria aggiuntiva riduce
il carico sui dischi e aumenta l‟ hit ratio2 mantenendo la stessa
paginazione. Si potrebbe intervenire direttamente sulla memoria di
cache del disco, ma in questo caso, la memoria extra verrebbe
1
Buffer pool: area di memoria in cui le pagine del database vengono lette, modificate e gestite durante
l'elaborazione.
2
Hit ratio: indice ottenuto dalla formula (# accessi logici – # accessi fisici) / (# accessi logici)
32
utilizzata esclusivamente per velocizzare le operazioni di quel disco
e non di tutto il sistema.
2.1.2.2.
I DISCHI
L‟aggiunta di dischi, in linea di principio, è indicata quando i dati
da gestire superano la capacità dei dischi in uso. In realtà i database
considerano la larghezza di banda un fattore più rilevante rispetto
alla capacità di archiviazione. Per migliorare la larghezza di banda
si può intervenire in due modi: o si aumenta la memoria di cache
dei singoli dischi o si acquistano nuovi dischi da inserire nello
Storage Subsystem. Quest‟ultima ipotesi comporta una serie di
vantaggi aggiuntivi, quali:
a) la possibilità di gestire i log su dischi separati garantendone
l‟accesso sequenziale in scrittura e lettura.
b) la possibilità di modificare il livello RAID in uso.
c) La possibilità di partizionare tabelle o applicazioni di grandi
dimensioni su diversi dischi logici per non sovraccaricare un
unico disco.
2.1.2.3.
I PROCESSORI
Che un sistema di database riesca a sovraccaricare un processore
moderno sembra a primo impatto quasi impossibile. Eppure si tratta
di qualcosa di estremamente concreto. Anche se un sistema di
database non opera sui dati come può ad esempio fare un
33
applicativo audio-visivo, le risorse di elaborazione necessarie al
database sono direttamente proporzionali ai dati da gestire. Quando
la mole di dati supera l‟ordine di grandezza del terabyte, l‟ipotesi di
aggiungere altri processori al sistema non appare più così insensata.
Il modo più economico per creare un sistema multiprocessore è
quello di collegare più sistemi informatici indipendenti tra loro con
una rete ad alta velocità. Questa soluzione può andare bene quando:
1. Una parte dell'applicazione può essere demandata ad un altro
sistema per essere lavorata separatamente.
2. Le applicazioni possono essere suddivise tra applicazioni di
elaborazione e di supporto. In questo caso si demandano le
applicazioni di supporto (che non modificano il database) agli
altri sistemi che, scaricato periodicamente il database dalla
rete (backend), eseguono in locale i compiti a loro assegnati.
3. Nel sistema ci sono molte transazioni di sola lettura e poche
transazioni in scrittura. E‟ difficile, infatti, garantire
l‟atomicità delle transazioni in scrittura ed evitare che si
creino sovraccarichi legati agli aggiornamenti.
4. Sia possibile il partizionamento dei dati. L'obiettivo da
perseguire è semplice: ogni grande struttura dovrebbe essere
partizionata in base al carico di lavoro ad essa associata e poi
suddivisa uniformemente su tutti i sistemi. In alternativa al
34
carico di lavoro è possibile considerare come parametro di
partizionamento il fattore tempo3.
Per il partizionamento delle tabelle in particolare, si parlerà di
Hash Partitioning o di Range Partitioning. Il primo metodo
partiziona i dati suddividendoli in base al valore di un record
di riferimento A e attraverso il calcolo di una funzione h detta
funzione di hash; il secondo metodo smista i dati della
struttura dividendoli tra quelli che contengono l‟attributo di
riferimento e quelli che non lo contengono.
5. E‟ possibile inserire una memoria condivisa con cui gestire i
dati necessari alle applicazioni che, a causa della loro
interconnessione, non è possibile partizionare.
Ci sono tre diversi tipi di sistemi multiprocessore:
1. Sistemi Tightly Coupled: che dispongono di diversi
processori ma di un'unica memoria logica principale e un
unico set di dischi.
2. Sistemi Shared Nothing: in cui ogni processore è dotato di
propria memoria principale e proprio set di dischi. Il lavoro
viene distribuito uniformemente e gli applicativi suddivisi in
una serie di sottoapplicativi indipendenti tra loro.
3
fattore tempo: ogni sistema dovrebbe contenere i dati legati ad un intervallo di tempo specifico.
35
3. Sistemi Shared Disk: in cui ogni processore ha la propria
memoria principale, ma set di dischi condiviso. Questa
architettura andrebbe bene al posto dei sistemi tightly coupled
quando gli applicativi tendono a produrre sovraccarichi ai
singoli sistemi.
Fig. 5: Rappresentazione schematica dei tre tipi di sistemi multiprocessore
2.2. TUNING DEL SISTEMA OPERATIVO
Per parlare di tuning a livello di sistema operativo è necessario fare una
panoramica dei concetti fondamentali riguardanti il suo funzionamento e
la multiprogrammazione.
Le performance di un sistema di database sono strettamente legate a quelle
del sistema operativo ospitante. Da qui la necessità di ottimizzare i threads
36
e il loro sistema di gestione e la necessità di un corretto utilizzo del buffer
del database e del file system.
2.2.1. GESTIONE DEI THREADS
Qualsiasi processo del sistema operativo viene suddiviso in più threads
che vengono poi eseguiti in ordine sequenziale o contemporaneo. Se
fino a qualche anno fa il multithreading si basava esclusivamente su
tecniche a divisione di tempo e scheduling  ogni thread veniva
eseguito per un certo periodo di tempo, poi passava il controllo ad un
altro thread  con l‟avvento dei sistemi multicore il parallelismo ha
assunto una connotazione reale. In termini di prestazioni, il tempo
necessario ad ogni thread è dato dal tempo di esecuzione delle sue
istruzioni, sommato al tempo necessario a passare il controllo al thread
successivo, sommato a quello legato ai tempi di attesa per eventuali
lock delle risorse comuni.
Il tuning del sistema operativo si concentra sull‟ottimizzazione dello
Scheduling e delle Priorità per ridurre appunto il tempo di esecuzione di
ogni thread.
2.2.1.1.
TUNING DELLO SCHEDULING
Per ottimizzare lo Scheduling ci sono due strategie:
1. Scegliere un sistema operativo che usi tecniche di switching
(dei thread) poco costose in termini di prestazioni;
37
2. Ridurre al minimo il numero di switches. Uno switch è
inevitabile quando l'applicazione esegue una richiesta di I/O;
per tutti gli altri casi, in cui il suo uso sarebbe opzionale, è
meglio evitarli. Questo vuol dire ridurre al minimo gli
interrupts e dare priorità all‟aumento del throughput
piuttosto che ai tempi di risposta. Il compromesso usato nei
moderni microprocessori consiste nell‟assegnare a ogni
thread un tempo di esecuzione massimo di un secondo,
valore sufficiente, nella maggior parte dei casi, per terminare
correttamente l‟esecuzione di un thread.
2.2.1.2.
GESTIONE DELLE PRIORITÀ
In un sistema che fa uso di priorità, le prestazioni del database
risultano influenzate negativamente quando:
1. I processi del database vengono eseguiti con una priorità più
bassa rispetto agli altri processi. Se le risorse disponibili
diminuiscono, il valore delle prestazioni del database precipita
a zero.
2. I threads vengono eseguiti tutti con la stessa priorità
generando i cosiddetti fairness4.
3. Si verificano casi di inversione di priorità. Dati tre thread con
priorità decrescente T1, T2 e T3, ipotizzato che al tempo t1
4
fairness: situazione che si verifica quando un thread pronto all‟esecuzione non può essere avviato
perché alcune risorse necessarie sono bloccate da altri thread.
38
venga avviata l‟esecuzione di T3 e che T3 richieda
immediatamente il lock di una risorsa in comune con T1, al
tempo t2 l‟esecuzione di T1 è pronta per essere avviata ma la
risorsa a lui necessaria è ancora bloccata. T1 e T3 vengono
deschedulizzati  T3 per la sua bassa priorità e T1 per
mancanza di risorse  e viene avviato ed eseguito il thread T2.
In definitiva, la superiore priorità di T1 non viene rispettata e
avviene uno “scavalcamento” da parte di T2.
Fig. 6: Schema che illustra il fenomeno dell‟inversione di priorità
In definitiva si avrà che, per evitare l‟inversione si dovrebbero
eseguire i threads tutti con la stessa priorità, per evitare i fairness, si
dovrebbe diversificarla il più possibile. Ecco nuovamente la
39
necessità di trovare un compromesso: la priorità dinamica. L‟idea
è quella di assegnare, ad ogni thread in avvio, priorità massima e
poi decrementarla ogni volta che il thread blocca una risorsa.
2.2.1.3.
Molti
LA MULTIPROGRAMMAZIONE
amministratori
credono
che
un
alto
livello
di
multiprogrammazione sia la soluzione migliore per i loro sistemi. È
vero che l‟aumento del numero di thread riduce i cicli inattivi dei
processori e quindi gli sprechi, ma è anche vero che provoca un
aumento della possibilità che il sistema risenta di un calo
prestazionale. Le cause di questo calo dipendono da:
 la quantità di RAM usata dagli utenti. Se supera la quantità
di memoria reale il sistema compensa con la paginazione
dell‟area riservata ai processi, il buffer e la memoria
secondaria.
 i conflitti di Lock derivati da un eccessivo numero di
transazioni eseguite contemporaneamente.
Un metodo valido per prevenire entrambi i casi consiste
nell‟incrementazione progressiva della concorrenza. Il metodo è
strutturato in tre fasi distinte:
1. Viene avviato il sistema utilizzando il minimo di transazioni
simultanee consentite.
40
2. Viene aumentato tale limite di uno e misurato l‟andamento
delle prestazioni del sistema.
3. Se le prestazioni subiscono un miglioramento, si procede ad
ulteriori aumenti del limite di concorrenza, altrimenti il
limite trovato è il massimo consentito senza calo di
prestazioni.
La grossa limitazione del metodo appena esposto è che non può
essere applicato ai database se non a fronte di un continuo
monitoraggio del sistema. Gerhard Weikum e i suoi studenti, sono
riusciti a trovare un metodo meno oneroso attraverso il calcolo
dell‟indice di criticità del sistema. Si tratta del rapporto tra il
numero di lock delle transazioni e il numero di lock totali. Quando
questo indice supera il 23% la possibilità di crash del sistema
diventa abbastanza concreta. Secondo Gerhard spetterebbe al
DBMS gestire questo indice ma, attualmente, nessun DBMS
implementa al suo interno le funzioni necessarie.
2.2.2. DATABASE BUFFER
E‟ stato visto che l‟accesso dei dati dal disco richiede, per
configurazione dell‟hardware, molto più tempo rispetto all‟accesso
degli stessi dati sulla RAM. Per minimizzare le prestazioni, il database
deve cercare di ridurre al minimo il numero di accessi alla memoria
secondaria. Ricordando la teoria sulle transazioni simultanee, si può
41
destinare una certa porzione di memoria virtuale, conosciuta come
buffer, database buffer o database cache, alla condivisione dei dati in
comune. L'impatto del buffer sul numero di accessi fisici dipende da tre
fattori:
1. Letture e scritture logiche: Quando le operazioni di lettura e
scrittura del sistema operano sulle pagine di memoria che fanno
parte del buffer.
2. Sostituzione delle pagine: A seguito di un‟operazione di scrittura
su disco può verificarsi la necessità di ricaricare alcune pagine
nel buffer. E‟ possibile minimizzare questa situazione attraverso
una buona gestione delle scritture da parte del database tuner5.
3. La paginazione del Sistema Operativo: Se lo spazio dedicato al
buffer supera lo spazio disponibile della memoria RAM il
sistema operativo integra lo spazio mancante procedendo alla
paginazione della memoria secondaria. Il tuner deve assicurarsi
che questo non succeda.
L‟aspetto importante consiste dunque nel capire come la presenza del
buffer influisce sul numero di accessi logici e fisici al disco. Il valore
del parametro Hit Ratio, presentato nel paragrafo 2.1.2.1, non solo
serve da indicatore del livello di ottimizzazione del sistema, ma aiuta
l‟amministratore nella scelta della dimensione di buffer più opportuna.
5
database tuner: inteso come i moduli software del DBMS che si occupano dell‟ottmizzazione
automatizzata della base di dati e, in caso di errori o rallentamenti, aiutano ad individuarne le cause.
42
Fig. 7: Schema di un Database Buffer
In generale, per raggiungere le prestazioni ottimali, esistono due
strategie:
1. Aumentare la dimensione del buffer fino ad ottenere un
appiattimento dell‟incremento di Hit Ratio mantenendo al
contempo basso il numero di sostituzioni delle pagine e la
paginazione dei dischi.
2. Acquistare e aggiungere RAM.
2.2.3. FILE SYSTEM
I File System permettono agli utenti di creare, eliminare, leggere e
scrivere flussi di informazioni organizzati in file. I principali parametri
regolabili per quanto riguarda il file System sono:
43
 La dimensione dei chunks6 del disco. Alcuni file System li
chiamano extent. Poiché molte query tendono a scansire solo
parti di file, per migliorare le prestazioni è bene specificare le
dimensioni della traccia relativa a ogni extent. Se si tratta di file
di grosse dimensioni è consigliato l'uso di extents grandi.
Quando invece l'accesso ad un file è completamente casuale un
piccolo extent riduce lo spreco di spazio.
 I fattori d‟uso sulle pagine del disco. Più alto è il fattore di
utilizzo, più completa può essere la pagina al momento in cui si
verificano degli inserimenti. Se si tratta di oggetti, ad esempio
tabelle, che prevedono numerosi aggiornamenti con a seguito un
aumento di dimensioni è bene mantenere un fattore di utilizzo
basso, in caso contrario un valore alto aiuta le scansioni da parte
delle query.
 Il numero di pagine che possono essere precaricate. Il
prefetching è utile per le query che scansionano i file. A meno di
una piccola quantità di RAM è bene che il numero di pagine
precaricate coincida quasi interamente a una traccia del disco.
 Il numero di livelli di back-link per accedere a una determinata
pagina. Questo punto assume particolare importanza per i
6
chunks: blocchi di memoria contigua in un file system riservati per un file. Quando si inizia a
scrivere un file, viene allocato un intero chunk. Quando si scrive di nuovo sul file, i dati vengono
scritti a partire dagli ultimi. Questo riduce la frammentazione dei file.
44
sistemi basati su Unix perché la struttura indicizzata dei file
prevede l‟inserimento di molti più back-link nelle pagine finali
piuttosto che nelle pagine iniziali di un file.
2.3. TUNING DEL DBMS
Le applicazioni di database dividono il loro lavoro in transazioni. Le
transazioni, come i threads, possono essere eseguite in parallelo o in modo
sequenziale purchè venga rispettata la loro proprietà di atomicità. Anche
per le transazioni valgono quindi le considerazioni esposte per il
multithreads e la multiprogrammazione: operare tuning equivale a trovare
il punto di incontro tra performance e concorrenza. Il tuning del DBMS si
basa su due principali aspetti: la gestione dei lock delle transazioni ed il
sistema di logging e recovery del database.
2.3.1. LOCKING TUNING
Per prima cosa è necessaria una breve panoramica su come funzionano
i lock nelle transazioni. Ci sono due tipi di lock: i write lock, che
garantiscono a una transazione l‟accesso esclusivo alla risorsa con la
possibilità di modificarne il contenuto, e i read lock che non bloccano
l‟accesso in lettura sulla risorsa alle altre transazioni ma bloccano
qualsiasi write lock.
Il sistema di gestione si basa poi su due semplici regole:
45
1. Una transazione deve ottenere il lock della risorsa X prima di
accedervi.
2. Se una transazione vuole ottenere il lock della risorsa Y deve
prima rilasciare la risorsa X.
Per quanto riguarda il tuning, l‟intervento dell‟amministratore può
consistere in:

Operare la cosiddetta Transaction Chopping, ovvero scomporre
una transazione articolata in più transazioni semplici;

Ridurre i lock eliminando quelli non necessari;

Favorire i lock condivisi piuttosto che i lock esclusivi;

Ridurre il tempo di ogni lock per migliorare i tempi di attesa tra
le transazioni.

Definire la granularità dei lock;
2.3.1.1.
TRANSACTION CHOPPING
La prima domanda che deve farsi l‟amministratore è: quanto deve
essere lunga una transazione? Per rispondere a questa domanda si
deve tener presente che:
1. Più lunga è la transazione, più sono le risorse necessarie alla
sua esecuzione e più facilmente può capitare che un‟altra
transazione rimanga in attesa di qualche risorsa bloccata;
46
2. Più lunga è l‟esecuzione della transazione A più tempo
un‟altra transazione dovrà aspettare per il rilascio delle
risorse bloccate da A.
Transazioni corte sono quindi migliori di transazioni lunghe in
termini di prestazioni. Ecco perché la necessità di cercare di
scomporre le transazioni più corpose in transazioni atomiche senza
perdere il livello di isolamento originale. A volte, per riuscirci, può
essere necessario riformulare l‟intera transazione.
2.3.1.2.
RIDURRE I LOCK
E‟ importante eliminare i lock superflui nel sistema. A questa
categoria fanno parte i lock generati quando viene eseguita una
transazione alla volta e quelli generati nonostante tutte le
transazioni siano di sola lettura.
2.3.1.3.
LA GRANULARITÀ DEI LOCK
I moderni sistemi di database permettono di distinguere e
specificare la granularità dei lock. In ordine decrescente di
granularità ci sono: i record-level lock, i page-level lock e i tablelevel lock. Un record-level lock impedirà l‟accesso simultaneo di
più transazioni a un determinato record, un page-level lock
impedirà l‟accesso a tutti i record che fanno parte di una
determinata pagina; un table-level lock opererà allo stesso modo
47
riferendosi però a tutte le pagine che compongono una specifica
tabella e quindi a tutti i record di quella tabella.
Utilizzare lock con granularità più alta, basandosi su una prima
impressione, sembrerebbe la scelta migliore. Un record lock,
permettendo a più transazioni che operano su record della stessa
pagina di essere eseguite contemporaneamente, dovrebbe, infatti,
produrre un miglioramento di prestazioni. In realtà, ogni
transazione difficilmente richiede l‟accesso a singoli record
all‟interno di una pagina e la scelta di usare record lock porterebbe,
al sistema, un inutile aumento di richieste di lock da gestire con
tutte le relative conseguenze in termini di tempi d‟attesa delle
singole transazioni.
In definitiva, per evitare i deadlock7 e di ridurre l‟overhead, è
consigliato l‟uso di page-level lock per transazioni brevi e tablelevel lock per transazioni più lunghe.
2.3.2. LOGGING TUNING
All‟interno del sistema possiamo classificare le transazioni in base al
loro stato. Una volta attivata una transazione, questa potrà o essere
eseguita o interrotta. A livello teorico gli effetti delle transazioni
eseguite dovrebbero essere permanenti mentre le transazioni interrotte
7
Deadlock: situazione di stallo tra più transazioni in cui ognuna aspetta il verificarsi di qualcosa per
sbloccare il proprio lock.
48
non dovrebbero lasciare traccia. Questo principio, apparentemente
facile da rispettare, in realtà dipende dal momento in cui la transazione
viene interrotta. Basta pensare a una transazione che prevede la
modifica di una serie di record e che viene interrotta a pochi istanti
dalla fine. Gli effetti di tale transazione restano nel sistema che, a
seguito dell‟interruzione, presenta record incongruenti e modificati
irreversibilmente. Tali record potrebbero diventare la causa di ulteriori
errori e interruzioni.
In generale si distinguono le interruzioni hardware, causate da un
malfunzionamento fisico, e le interruzioni software, causate da errori di
programma.
E‟ stato visto che, la risoluzione dei problemi legati alle interruzioni
hardware, prevede l‟uso di sistemi fault tollerance. Per quanto riguarda
invece le interruzioni software, la soluzione è il sistema di logging e
recovery. In pratica, quando si presenta un‟interruzione, il sistema deve
poter ripristinare il dato originale e poi decidere se riavviare o meno la
transazione che ha generato l‟interruzione. Per farlo si serve di appositi
file di log.
Si tratta di file che contengono una serie di azioni organizzate in record
di tipo REDO e UNDO a cui sono associati i valori dei dati originali e
dei dati modificati a seguito di una transazione. Lo scopo del tuning è
ottimizzare il processo di creazione e gestione di questi file.
49
In particolare l‟amministratore deve assicurarsi che:
1. La scrittura dei file di log avvenga con accesso sequenziale al
disco (ovvero i file di log vengano creati su dischi separati dai
dati)
2. Le informazioni contenute in ogni record di log siano minime
così da permettere l‟inserimento di più aggiornamenti nella
stessa pagina.
3. Venga rispettato il protocollo Write-Ahead Logging (WAL).,
ossia che tutte le modifiche prima di essere apportate fisicamente
devono essere inserite in un record di log.
4. Siano garantiti i principi di atomicità e durabilità delle
transazioni.
2.4. TUNING APPLICATIVO
La maggior parte delle applicazioni che interagiscono con i sistemi
database, lo fanno in due modi: attraverso l‟utilizzo di un linguaggio
specifico di quarta generazione o mediante l‟utilizzo di un linguaggio di
programmazione come PHP, Java, Visual Basic, C, ecc. che si basano su
un'interfaccia a livello di chiamata. Diversi fornitori offrono numerosi
software proprietari di quarta generazione che risolvono le query
ottenendo i risultati desiderati con esecuzioni di alto livello prestazionale
a costo della portabilità di tali applicazioni. I programmi che
50
interagiscono, invece, con il database mediante interfaccia a livello di
chiamata, si basano su librerie di funzioni che consentono loro di
connettersi ad un database server, eseguire istruzioni SQL, recuperare i
risultati della query ed eseguire o interrompere le transazioni.
2.4.1. MODELLO CLIENT-SERVER
Poichè l‟esecuzione dell‟applicativo dei client è asincrona rispetto al
funzionamento del database server, la connessione tra i due può essere
possibile solo mediante un buffer di memoria. L‟utilizzo di questo
modello di interconnessione offre due principali vantaggi:
 Se l‟interazione con il client è molto lenta e, ad esempio, i tempi
per la lettura delle risposte di una query sono eccessivamente
lunghi, l‟utilizzo del buffer di memoria permette al database
server di memorizzare all‟interno del buffer l‟intero risultato
della query e svincolare subito le proprie risorse senza risentire
delle basse prestazioni del client.
 I dati vengono inviati dal server al client non appena il buffer di
comunicazione lato server si riempie o non appena termina
l‟esecuzione del processo attivo. L‟uso di buffer grandi avrà
quindi l‟effetto di allungare i tempi di risposta percepiti dal
client riducendo però il numero di pacchetti che attraversano la
rete e quindi il rischio di errori. L‟uso di un piccolo buffer,
51
d‟altra parte, avrà l‟effetto opposto. Come sempre la parola
chiave è „equilibrio‟.
Fig. 8: Modello Client Server con sistema di buffer
2.4.2. TUNING DELLE INTERFACCE APPLICATIVE
Analizzare l‟interfaccia applicativa utilizzata dall‟utente per interagire
con il DBMS alla ricerca di codici dal basso rendimento spesso è di
cruciale importanza ai fini delle prestazioni. I principali principi che
l‟interfaccia deve rispettare sono:
1. Evitare l‟interazione con l‟utente all‟interno di una transazione.
2. Ridurre al minimo il numero di passaggi d‟esecuzione tra
applicazione e database server.
3. Recuperare solo le righe e le colonne necessarie.
4. Minimizzare il numero di query da compilare.
5. Utilizzare lock ad alta granularità.
52
3. TUNING DEL DATABASE
Se fino ad ora sono stati presentati una serie di interventi mirati
all‟ottimizzazione del sistema su cui il database opera, adesso verranno
analizzate le operazioni che l‟amministratore può compiere direttamente sulla
struttura dati per migliorarne al massimo l‟efficienza. In particolare, dando per
assodata la conoscenza delle progettazione del modello concettuale del
database (modello E/R), vedremo quali sono i possibili interventi di tuning
prima sul livello logico e poi sul livello fisico della base di dati.
3.1. TUNING A LIVELLO LOGICO
La progettazione logica si occupa di definire l‟organizzazione dei dati e di
stabilire:
1. gli attributi relativi alle entità già definite a livello concettuale
2. le chiavi primarie ed esterne per la concretizzazione delle relazioni
emerse dal modello E/R.
In generale, si definisce attributo un‟informazione relativa ad un‟entità che
rispetti le seguenti regole:
 contiene un‟unica informazione.
 Non assume valori costanti.
53
 Non si tratta di un campo il cui valore può essere calcolato tramite
operazioni su altri campi.
Una volta definiti in questo modo gli attributi del modello logico, si
procedere alla concretizzazione delle relazioni del modello E/R e alla
creazione di speciali attributi definiti come chiavi primarie ed esterne.
Per potere due attributi rappresentare una relazione, ed essere quindi
chiave primaria ed esterna, devono soddisfare le seguenti condizioni:
1. Devono avere la stessa natura. Se un attributo è di tipo intero e
l‟altro è di tipo testo i due attributi insieme non possono mai
rappresentare una relazione tra entità.
2. Devono avere sempre valori “not null”
3. Almeno uno dei due attributi deve essere univoco.
L‟utilizzo delle chiavi permette di rappresentare fisicamente le relazioni di
cardinalità uno a molti ma, da sole, non sono sufficienti alla concretizzazione
delle relazioni con cardinalità molti a molti. Per risolvere questo problema,
rendere la struttura più flessibile, ridurre la ridondanza e il rischio di
incoerenza, occorre procedere a una serie di operazioni dette di
normalizzazione. La normalizzazione aiuta a mantenere alte le prestazioni
anche se, in certi casi, si possono raggiungere risultati migliori con l‟aggiunta
di ridondanza e quindi la parziale denormalizzazione del modello.
54
3.1.1. NORMALIZZAZIONE
Dopo aver stabilito le entità, gli attributi e le chiavi che andranno a
comporre il modello fisico del database al fine di raggiungere lo scopo
previsto dalla base di dati, per ottenere il massimo dell‟efficienza è
necessario procedere alla normalizzazione dello schema realizzato. Tale
processo si fonda su un unico semplice criterio: se una relazione
presenta più concetti tra loro indipendenti, la si decompone in relazioni
più piccole, una per ogni concetto.
Questo tipo di processo non è sempre applicabile in tutte le tabelle. In
taluni casi potrebbe comportare una perdita d'informazioni. Esistono
vari livelli di normalizzazione detti anche forme normali che certificano
la qualità del modello di un database.
In genere si ritiene che l‟applicazione delle prime tre forme normali
permetta di raggiungere un adeguato compromesso tra efficienza e
ridondanza.
Un modello logico si dice:
 in Prima Forma Normale, quando ogni tabella non presenta
gruppi di attributi ripetuti  ciascun attributo è definito su un
dominio con valori atomici  e contiene un attributo che funge
da chiave primaria
 in Seconda Forma Normale, quando il modello è in Prima Forma
Normale e, in più, per ogni tabella tutti i campi non chiave
55
dipendono funzionalmente dalla chiave primaria o, in caso di
chiave composta, da tutti gli attributi che ne fanno parte.
 In Terza Forma Normale, quando il modello è in Seconda Forma
Normale e la dipendenza tra gli attributi è basata solo sulla
chiave primaria e non esistono dipendenze tra attributi.
Sono state formalizzate altre forme normali quali: la forma normale
Boyce/Codd, la quarta forma normale, la quinta, ecc. ma raramente
vengono
utilizzate,
in
quanto
ad
un
incremento
di
rigore
nell'eliminazione della ridondanza corrisponde un degrado delle
prestazioni. Per capire bene la normalizzazione può essere utile un
esempio.
Di seguito è preso in considerazione lo schema, attualmente
funzionante, del database dei docenti di religione di una Diocesi le cui
funzioni principali consistono nel calcolo della graduatoria e
nell‟assegnazione delle cattedre, definite come insieme di ore di
servizio distribuite in un massimo di tre scuole diverse, ai singoli
insegnanti.
56
Fig. 9: Elenco attributi della tabella Insegnanti.
La prima cosa che notiamo dalla struttura della tabella Insegnanti è che
il suo secondo attributo (COGNOME_NOME) viola una delle
caratteristiche di definizione degli attributi. Esso non rappresenta infatti
un‟informazione univoca bensì l‟unione del cognome e del nome
dell‟insegnate. Anche correggendo questo errore, si ci rende conto che
la struttura ottenuta (Fig. 10) non rispetta le regole della prima forma
normale.
Fig. 10 Struttura della tabella dopo la correzione dell‟attributo COGNOME_NOME.
57
Pur esistendo il campo ID_ASPIRANTE che funge da chiave primaria,
sono presenti gruppi di attributi ripetuti. Applicare la prima forma
normale significherebbe eliminare tutti gli attributi sovrabbondanti e
semplificare la consultazione dei dati che appare confusionaria e di
difficile consultazione (Fig. 11).
Fig. 11: Visualizzazione dei dati della tabella non normalizzata
Gli effetti della normalizzazione di primo livello (Fig. 12) sono i
seguenti:
 Effetti Positivi: si riducono gli sprechi di spazio legati alle tuple
lasciate incomplete, si semplificano le interrogazioni e
soprattutto si rende la struttura più elastica permettendole di
memorizzare per ogni insegnante un numero massimo indefinito
di scuole al posto delle tre che prevedeva inizialmente
 Effetti Negativi: aumentano le tuple inserite nella tabella e la
ridondanza dei dati in relazione all‟anagrafica degli insegnanti;
58
Fig. 12: I dati della tabella insegnanti a seguito della normalizzazione di primo livello.
Per semplificare e rimuovere la nuova ridondanza, ci viene incontro il
principio della Seconda Forma Normale. In questo caso possiamo
notare che non tutti gli attributi della tabella dipendono funzionalmente
dalla chiave primaria già definita bensì è possibile scomporre gli
attributi in due gruppi: quelli legati all‟anagrafica e quelli che invece
dipendono dalla scuola di insegnamento. Si procedere, quindi, alla
normalizzazione di secondo livello aggiungendo una chiave primaria ID
legata alla scuola di riferimento, una chiave esterna ID_INSEGNANTE
e spezzando la struttura in due strutture distinte.
59
Fig. 13: I dati nelle due strutture distinte.
Dallo studio di questa nuova situazione iniziale si ci rende conto che,
mentre la tabella insegnanti risulta adesso normalizzata al secondo
livello, la nuova tabella Scuole continua a non essere normalizzata in
quanto l‟attributo PER_ORE e ANNO non sono legate esplicitamente
alla chiave primaria ID_SCUOLA. Procedendo come già esposto e
normalizzando ulteriormente in secondo livello si avrà alla fine la
seguente struttura:
60
Fig. 14: I dati dopo la normalizzazione di secondo livello.
Se da un lato la Seconda Forma Normale ha rimosso quasi interamente
le ridondanze, dall‟altro ha complicato le query che ora devono tenere
conto delle nuove relazioni tra le tre strutture. Analizzando
ulteriormente l‟esempio proposto e trascurando la ridondanza del
campo DI della tabella Scuole per cui sarebbe necessaria un‟ulteriore
normalizzazione di secondo livello, si ci rende conto che la struttura è
già in terza forma normale perché nessun campo attributo dipende da
un altro campo attributo.
3.1.2. DENORMALIZZAZIONE
Denormalizzazione significa violare la normalizzazione. Tenuto conto
di tutti gli svantaggi di una tale mossa, l‟uso della denormalizzazione è
61
funzionale esclusivamente ad un aumento di prestazioni che va
comunque valutato da caso a caso. Il miglioramento dell‟esecuzione di
certe query con l‟inserimento di ridondanza produce, infatti, un
peggioramento rispetto alle operazioni di modifica e inserimento dei
record. Come regola generale, denormalizzare fa male alle prestazioni
per le relazioni che vengono aggiornate spesso ma può aiutare in
situazioni di basso aggiornamento.
Eseguire la denormalizzazione consiste o nell‟aggiunta di un campo
ridondante specifico o nella trasformazione delle relazioni gerarchiche
Throughput (Queries/sec)
di tipo uno a molti in un'unica relazione e quindi in un'unica tabella.
0.002
0.0015
0.001
0.0005
0
normalized
denormalized
Fig. 15: Normalizzazione e Denormalizzazione.
La figura 15, tratta da Shasha/Bonnet 2004, pag. 136, è un
grafico dei potenziali vantaggi di denormalizzazione relativi
all‟esecuzione di una query che mostra tutti gli oggetti venduti da
62
un fornitore in Europa. La versione normalizzata richiede un join a
quattro vie tra Oggetti, Fornitori, Nazioni e Regioni. Aggiungendo
gli opportuni campi di ridondanza è possibile rimuovere i quattro
join e trasformare la query in una semplice selezione sugli oggetti.
La denormalizzazione fornisce, in questo caso, un miglioramento
del 30% del throughput.
3.1.3. OVERNORMALIZZAZIONE
Quando una tabella diventa eccessivamente voluminosa, soprattutto nei
sistemi di gestione dati delle grosse imprese, può essere utile ai fini
delle prestazioni, spezzare i dati contenuti in due tabelle distinte. La
ricerca di un campo in un set di cinquanta milioni di record è infatti
molto più veloce di una ricerca su un set di cento milioni di record.
Naturalmente, anche qui bisogna valutare attentamente i pro e i contro
perché se da un lato l‟overnormalizzazione può migliorare le
prestazioni, dall‟altro complica le operazioni di modifica e inserimento.
Sdoppiare una tabella equivale a sdoppiare gli indici e tutte le
problematiche inerenti alla gestione della tabella originale con una
quantità di elementi però dimezzata. La vera domanda è: ne vale la
pena?
63
3.2. TUNING A LIVELLO FISICO
Il tuning del database a livello fisico è forse la parte di tuning più delicata
e rilevante di tutte. Se un errore sugli altri livelli comporta generalmente
solo un calo di prestazioni, uno sbaglio sul livello fisico del database può
portare al crash dell‟intero sistema. I principali aspetti trattati riguardano
la creazione e la gestione degli indici e l‟ottimizzazione delle query SQL.
3.2.1. TUNING DEGLI INDICI
Un indice può essere visto come un insieme di coppie del tipo (K,P)
dove:
 K è un valore chiave del campo su cui l‟indice è costruito;
 P è un puntatore al record con valore di chiave K.
Ci sono due tipi di chiavi K: chiavi sequenziali, che assumono un
valore monotono in base all‟ordine di inserimento del record, e chiavi
non-sequenziali il cui valore non dipende dall‟ordine di inserimento. Il
vantaggio nell‟uso degli indici nasce dal fatto che la chiave è solo parte
dell‟informazione contenuta in un record e pertanto, occupando uno
spazio minore rispetto al file dati, permette di velocizzare le operazioni
di ricerca.
Per entrare in merito al tuning degli indici è bene fare prima una
panoramica dei tipi di query in cui gli indici saranno poi usati.
64
 Equality Query: sono query che selezionano un certo numero di
record basandosi su un‟operazione di confronto di uguaglianza.
Si distinguono le point query che restituiscono un solo record,
dalle multipoint query, che ne restituiscono diversi. Ecco degli
esempi:
POINT QUERY
MULTIPOINT QUERY
SELECT Cognome, Nome
FROM Insegnanti
WHERE ID_Aspirante=1
SELECT Nome
FROM Insegnanti
WHERE Cognome=”Rossi”
La point query restituisce sempre e solo un record, la multipoint
query restituisce tutti i nomi delle persone che fanno di cognome
Rossi.
 Range Query: sono query che selezionano i record il cui attributo
X assume valori compresi in un predefinito intervallo. Ad
esempio:
SELECT *
FROM Insegnamenti
WHERE PER_ORE<18
 Prefix Query: si tratta di una query che, basandosi su un attributo
o una sequenza di attributi X, seleziona tutti i record che hanno
un predefinito prefisso in X. Ad esempio:
SELECT Cognome
FROM Insegnanti
WHERE Cognome=„RO%‟
65
 Extremal Query: si tratta di una query che visualizza tutti i
record il cui attributo o insieme di attributi X assume valore di
minimo o di massimo. Ad esempio:
SELECT *
FROM Insegnamenti
WHERE Per_Ore = MAX ( SELECT Per_Ore FROM Insegnamenti )
 Ordering Query: si tratta di query che visualizzano un set di
record ordinandoli in modo Crescente o Decrescente rispetto ad
un attributo o ad un insieme di attributi X. Ad esempio:
SELECT *
FROM Insegnanti
ORDER BY Cognome, Nome
 Grouping Query: si tratta di query che raggruppano i risultati
trovati rispetto a un determinato attributo o gruppo di attributi X.
Ad esempio:
SELECT Anno, SUM(Per_Ore)
FROM Insegnamenti
GROUP BY Anno
 Join Query: si tratta di query che collegano due o più tabelle. Le
Join Query sono anche chiamate Equality Join Query perché la
fusione è ottenuta ponendo l‟uguaglianza tra chiavi primarie e
chiavi esterne. Ad esempio:
SELECT Cognome, Nome, Per_Ore
FROM Insegnanti, Insegnamenti
WHERE Insegnanti.ID_Aspirante=Insegnamenti.ID_Aspirante
66
Le prestazioni di ogni tipo di query variano comunque in base al tipo di
indice
definito
sulla
struttura
dati.
Gli
indici
differiscono
essenzialmente per il modo con cui organizzano l‟insieme di coppie
(K,P). I database supportano diversi tipi di organizzazioni strutturali.
Le principali sono: gli alberi binari e le tabelle di hash.
Tutte e due queste strutture, indipendentemente dalla loro concreta
implementazione, possono essere viste a loro volta come strutture ad
albero. Ci saranno nodi dell‟albero posizionati nella memoria RAM e
altri, in genere le foglie, posizionate nella memoria disco. Le
prestazioni della struttura dati saranno inversamente proporzionali al
numero di livelli dell‟albero. Una possibile tecnica per ridurre al
minimo tale numero è quello di massimizzare il numero di indici di
ciascun nodo figlio dell‟albero (fanout). Per migliorare le prestazioni
delle range query, ed eliminare eventuali bottleneck, è infine
consigliato implementare la struttura ad albero con l‟aggiunta di link
nei nodi foglia (ed eventualmente anche nei nodi interni) verso il nodo
alla loro destra.
3.2.1.1.
INDICI CON STRUTTURA B-TREE
Un B-Tree è un albero bilanciato le cui foglie contengono una serie
di coppie chiave/puntatore. Tali indici sono ordinati in base al
valore delle chiavi. Valutazione: I B-Tree sono, in generale la
migliore struttura per l‟organizzazione degli indici del database in
67
quanto raramente richiedono di essere riorganizzati, e possono
supportare diversi tipi di query diverse. Sono ad esempio
particolarmente appropriati per le range query, le prefix query e le
extremal query mentre sono poco adatti per le equality query. Con
inserimenti non sequenziali frequenti, la struttura B-tree avrà tempi
di risposta più coerenti rispetto alle strutture di hash in quanto è in
grado di gestire catene di overflow di lunghezza illimitata. Essendo
l‟efficienza legata al numero di livelli e quindi legata al valore di
fanout, all‟aumentare della lunghezza della chiave si riduce nel
nodo lo spazio per la memorizzazione di altri indici, aumentano i
livelli e si riducono le prestazioni.
3.2.1.2.
INDICI CON STRUTTURA HASH
Le strutture di Hash si basano su un metodo che prevede
l‟archiviazione degli indici in riferimento al valore assunto da una
funzione chiamata funzione di hash. Data una chiave, la funzione
hash restituisce la posizione del record sottoforma di indirizzo della
pagina che lo contiene o della prima pagina di una catena di
overflow. Valutazione: la struttura Hash è particolarmente utile per
tutti i tipi di equality query. Nel caso delle point query migliora
ulteriormente le prestazioni se non sono presenti catene di
overflow; per le multipoint query, invece, il miglioramento è legato
all‟uso degli indici clustering. Le prestazioni di una struttura di
68
hash variano sensibilmente in base alla scelta della funzione hash,
ma i moderni sistemi di database riescono a valutare e scegliere
automaticamente tale funzione in base alle necessità. L‟uso di
questa struttura è, ad ogni modo, sconsigliata per tutte le query che
richiedono la consultazione di grandi quantità di dati.
Gli indici si distinguono anche in: Sparse e Dense Index, Clustering
Index, Nonclustering Index e Composite Index.
3.2.1.3.
STRUTTURE A INDICI DENSI E SPARSI
Un struttura ad indici si dice sparsa quando i puntatori della
struttura sono associati alle pagine dei dati; una struttura si dice
invece a indici densi quando ogni puntatore è associato a uno
specifico record della tabella.
In generale diremo che il numero di puntatori negli indici densi
saranno uguali al numero di puntatori negli indici sparsi per il
numero dei record di una pagina. Un vantaggio significativo delle
strutture ad indici densi è che possono eseguire query di lettura più
velocemente sfruttando informazioni interne.
3.2.1.4.
CLUSTERING INDEX
Un clustering index su un attributo o un insieme di attributi X
(chiamato anche indice primario) è un indice che alloca
69
contemporaneamente tutti i record in cui valori di X sono "vicini"
tra loro. Il concetto di vicinanza dipende dalla struttura dati. Gli
alberi binari considerano due valori X vicini basandosi sul loro
ordinamento (A e B, ad esempio, sono vicini. A e G non lo sono).
Le strutture di hash considerano invece vicini due valori solo se
sono identici. E‟ per questo motivo che le strutture clustering B-tree
sono più funzionali per le query di tipo: partial, range, multipoint,
point e join. Viceversa le strutture di hash sono più utili per le
query equijoin, point e multipoint. Visto che un clustering index
implica una certa organizzazione strutturale, è possibile definirne al
massimo uno per ogni tabella.
Un indice clustering offre i seguenti vantaggi rispetto ad un indice
nonclustering:
 Se l'indice cluster è sparso, memorizzerà meno puntatori
rispetto a un indice denso.
 Un indice cluster è buono per le query multipoint e per
eseguire un equijoin su un attributo con pochi valori.
 Un indice cluster basato su una struttura B_Tree è indicato
per le range, le prefix e le ordering query.
Lo svantaggio principale dell‟uso di questo tipo di indice è che i
suoi benefici diminuiscono all‟aumentare degli overflow.
70
3.2.1.5.
NONCLUSTERING INDEX
Un indice noncluster su un attributo o un insieme di attributi Y
(chiamato anche indice secondario) è un indice che non pone
nessun vincolo sull'organizzazione della tabella. La struttura può
essere quindi raggruppata in riferimento a un qualsiasi suo attributo
X. Un indice nonclustering è sempre di tipo denso. In ogni tabella
possono esere definiti molteplici indici nonclustering. L‟effetto
della presenza di uno o più di questi indici consiste nella possibilità
di eliminare la necessità di accedere alla tabella risolvendo
direttamente la query con le informazioni contenute negli indici
stessi. In genere avremo quindi che:
 Un indice nonclustering migliora le prestazioni se permette
di evitare del tutto l‟accesso alle pagine dei dati.
 Un indice nonclustering migliora tutte le point query.
 Un
indice
nonclustering
produrrà
un
miglioramento
prestazionale nelle multipoint query, quando il numero dei
record risultanti saranno esiguo.
Per stabilire se conviene l‟utilizzo di un indice nonclustering su una
query multipoint, si può verificare se il numero di valori distinti
della chiave è maggiore di C per il numero di record in ogni pagina,
dove C rappresenta il numero di pagine che il sistema è in grado di
precaricare dal disco (prefetching).
71
3.2.1.6.
COMPOSITE INDEX
Un Indice Composto (o indice concatenato) è un indice basato su
più di un attributo. E‟ possibile definire indici composti di tipo
clustering o nonclustering.
Una struttura di dati con un Composite Index denso sugli attributi
(A, B, C,...) archivierà un insieme di puntatori su tutti i record con
il valore A all‟interno del quale sarà già stato archiviato l‟insieme
dei puntatori ai record di valore B, ecc.
Gli Indici Compositi offrono i seguenti vantaggi:
 Una query su tutti gli attributi di un indice composto
restituirà un insieme di record molto più piccolo rispetto a
una query eseguita individualmente sugli stessi attributi.
 Un indice composto è un mezzo efficace per garantire
l'unicità di un insieme di attributi. Usando l‟indice composto
gli attributi individuali che compongono l‟indice possono
non essere unici purchè siano unici i valori ottenuti dalla
loro combinazione.
 Un indice composto semplifica le query di natura geografica,
perché permette una facile indicizzazione delle posizioni
geografiche (definite come coppia di valori latidune e
longitudine).
72
Gli svantaggi legati all‟uso di indici composti sono invece i
seguenti:
 Gli indici tendono ad occupare molto spazio per la
memorizzazione della chiave. Si pensi infatti alle strutture
B-Tree: memorizzare chiavi grandi equivale ad avere molti
livelli i cui nodi più bassi occupano la memoria disco e
quindi richiedono più tempo per la lettura. Implementare un
indice composto attraverso una struttura di tipo hash risolve
il problema delle dimensioni ma non permette l‟uso di
questo tipo di indice per le prefix e range query.
 Poiché un indice composto comprende diversi attributi,
l‟aggiornamento anche di uno solo di questi causerà la
modifica dell'indice.
Riassumendo quanto è stato detto sugli indici, ai fini del tuning
possiamo concludere che:
1. La scelta di una struttura hash è la più appropriata per quanto
riguarda le equality query, per il resto le prestazioni migliori si
ottengono da una struttura B-Tree.
2. La scelta di utilizzare indici clustering o nonclustering dipende
dal numero di record che si ci aspetta di ottenere dalle query. Per
73
gruppi di pochi record è quindi consigliabile l‟uso di indici
nonclustering.
3. E‟ meglio non usare nessun indice se il tempo che si perde per il
suo inserimento nella struttura scelta o per il suo aggiornamento
supera il tempo impiegato dalla query senza indice.
3.2.2. TUNING DELLE QUERY
In aggiunta all‟uso degli indici, il tuning prevede una serie di
accorgimenti, nel codice SQL delle query, che migliorano le
prestazioni. In particolare l‟amministratore dovrà cercare di:
1. Minimizzare l‟uso della clausola DISTINCT
2. Usare le query annidate
3. Usare i Trigger.
3.2.2.1.
L’USO DI DISTINCT
La clausola Distinct è utile in due casi: quando i risultati della
SELECT contengono duplicati e quando i campi restituiti non
dipendono dalla chiave definita dalle clausole FROM e WHERE.
In realtà capita spesso che DISTINCT venga usato anche quando
non è necessario, comportando uno spreco di risorse di
elaborazione. In generale si può dire che, definendo privilegiata la
74
tabella T se i campi restituiti dalla query contengono una chiave di
T, l‟uso di DISTINCT è superfluo quando:
1. Tutte le tabelle menzionate dalla query sono privilegiate;
2. Ogni tabella non privilegiata è direttamente collegata a una
tabella privilegiata.
3.2.2.2.
L’USO DI QUERY ANNIDATE
Anche se può sembrare impossibile, l‟uso di query annidate
produce prestazioni migliori alle corrispondenti versioni non
annidate. Esistono quattro tipi di query annidate:
1. Sottoquery non correlata8 con operatori aggregati nella query
interna
2. Sottoquery non correlata senza operatori aggregati
3. Sottoquery correlata con operatori aggregati
4. Sottoquery correlata senza operatori aggregati
Le sottoquery usate più frequentemente sono le prime tre. Se per
quanto riguarda la prima non ci sono particolari considerazioni in
merito alle prestazioni, quando si usano sottoquery del secondo e
del terzo tipo bisogna stare attenti agli indici e alla forma sintattica
usata valutando il codice migliore dell‟intera query da caso a caso.
8
Sottoquery non correlata: una sottoquery si dice non correlata se non contiene riferimenti alle
tabelle menzionate nella query principale.
75
3.2.2.3.
I TRIGGER
Il Trigger è una procedura che viene eseguita in maniera automatica
in coincidenza di un determinato evento, come ad esempio la
cancellazione di un record di una tabella. In questo modo si ha a
disposizione una tecnica per specificare e inserire vincoli di
integrità anche complessi.
In generale non ci sono particolari operazioni di tuning volte a
migliorare le prestazioni del sistema dovute ai trigger. La scelta
dell‟amministratore consiste solo nel loro uso o meno.
Il vantaggio legato all‟uso è appunto quello che, poiché i trigger si
verificano solo dopo una certa combinazione di operazioni, è
possibile usare queste informazioni per definire strategie speciali
volte a ridurre l‟eventuale calo di prestazioni che segue determinati
eventi.
Gli svantaggi sono:
1. In presenza di trigger, nessun aggiornamento può essere
analizzato e valutato isolatamente perché tale aggiornamento
può causare a sua volta trigger che eseguono ulteriori
modifiche.
2. La presenza di numerosi trigger può creare confusione. Non
esiste un vero e proprio sistema di gestione. Diversi trigger
possono essere definiti in relazione al verificarsi dello stesso
evento o essere sequenziali gli uni agli altri. Toccherebbe al
76
sistema scegliere, in casi di trigger multipli, quali eseguire
per prima e se eseguirli tutti o meno ma non è chiaro cosa
accadrebbe se molti trigger provassero a modificare gli stessi
dati.
77
4. APPLICAZIONE PRATICA DEL TUNING
Dopo aver visto e approfondito i vari livelli di tuning, nasce spontaneo il
desiderio di studiare e quantificare quali siano gli effetti concreti
dell‟applicazione dei concetti teorici finora esposti.
Prima di descrivere il progetto pratico e i risultati ottenuti, sembra doverosa
una breve premessa.
4.1. I BENCHMARK
Con il termine benchmark si intende un insieme di test software volti a
fornire una misura delle prestazioni di un sistema in riferimento a diverse
operazioni. Nell‟ambito dei database, a causa dell‟espansione e della
diversificazione del mercato informatico, è stato istituito un organismo
internazionale denominato Transaction Processing Performance Council
(TPC) che si occupa di definire benchmark standard e di omologare i
risultati ottenuti al fine di rendere comparabile la misurazione delle
prestazioni di un sistema rispetto agli altri. I benchmark del TPC sono
ritenuti i più importanti e significativi ai fini della valutazione di sistemi
che ospitano DBMS. I principali benchmark in uso sono:
78
 TPC-C, benchmark standard per la misurazione delle prestazioni di
un database in una rete aziendale. Utilizza tipicamente una struttura
di nove tabelle e un mix di cinque transazioni. Il test è piuttosto
complesso. Per ogni transazione vengono misurati i tempi specifici
nell‟ipotesi di un elevato numero di “client”.
 TPC-H, benchmark standard per i Dataware House. Si tratta di una
base di dati costituita da otto tabelle che rappresentano i dati
gestionali di un'azienda. I test vengono eseguiti generalmente su un
carico di 10.000.000 di record per una dimensione totale di 1GB
circa. Per analizzare le prestazioni del sistema vengono utilizzate
22 transazioni piuttosto complesse lanciate in streams differenti.
Ogni benchmark viene definito con un documento di specifiche molto
ampio e completo che ne definisce ogni aspetto. Per essere pubblicati i
risultati dei benchmark debbono essere validati da un Advisor e vanno
accompagnati da un documento che riporta tutti i dettagli della
configurazione e delle prove svolte. L'impegno per effettuare un
benchmark ufficiale è molto oneroso e in genere viene richiesto e
sostenuto solo dai principali venditori di hardware e software a fronte del
rilascio di nuovi e significativi prodotti.
79
4.2. SISTEMI DI ARCHIVIAZIONE MYSQL
MySQL permette di utilizzare numerosi tipi diversi di tabelle, ovvero
diversi "storage engine" (motori di archiviazione) per la memorizzazione
dei dati. La distinzione più importante fra i diversi sistemi è quella fra
transazionali e non transazionali. I motori transazionali offrono il
vantaggio di essere fault tollerance, quelli non transazionali sono però più
veloci, richiedono meno utilizzo di spazio su disco e meno memoria per
gli update.
MySQL implementa i due motori attraverso due principali standard:
MyISAM e InnoDB.
4.2.1. MYISAM
È lo storage engine di default di MySQL. Si tratta di un sistema non
transazionale e prevede l‟utilizzo di tre file: un file .frm che contiene la
definizione della tabella, più un file .MYD per i dati e un file .MYI per
gli indici. È possibile indicizzare anche colonne di tipo BLOB e TEXT
permette di gestire una colonna di tipo AUTO_INCREMENT per ogni
tabella, incrementando il suo valore per ogni record inserito
automaticamente.
4.2.2. INNODB
È uno storage engine transazionale ottimizzato per l'uso concorrente dei
dati fra molti utenti. Supporta l‟utilizzo delle FOREIGN KEY e si
differenzia da MyISAM per le seguenti caratteristiche:
80
 riesce a riparare una tabella dopo un crash di sistema
rieseguendo le ultime istruzioni registrate nei file di log.
MyISAM deve invece eseguire una scansione completa della
tabella per poi ripararla, ed eventualmente ricostruire gli indici;
 gestisce in maniera autonoma la cache mentre MyISAM si affida
al sistema operativo per il caching delle letture e delle scritture
sulle tabelle;
 immagazzina i nuovi record seguendo l‟ordine della chiave
primaria mentre MyISAM generalmente immagazzina i record
nell'ordine in cui sono inseriti;
 comprime i record molto meno rispetto a MyISAM. Questo
significa che richiede più memoria RAM e più spazio su disco;
 non supporta le ricerche fulltext.
4.3. IMPLEMENTAZIONE
Lo scopo del progetto è quello di comparare le prestazioni di una base di
dati di grandi dimensioni al variare del suo sistema di archiviazione in
presenza e assenza di indici. Per fare questo, si è scelto di appoggiarsi al
benchmark standard TPC/C.
Il suo utilizzo garantisce la veridicità dei valori ottenuti dai test e da
concretezza al progetto.
81
Per prima cosa è stato definito il database tpccprova in MySQL e,
seguendo le specifiche riportate dallo standard TPC/C, è stata definita la
struttura del database. In seguito sono stati generati e caricati, con un
apposito script SQL, una quantità di dati fittizi tali da omologare il
database come da specifiche TPC/C su scala 16.
TABELLA
NUM. RECORD
BYTE/RECORD
TOTALE BYTE
16
89
1,39 Kb
160
95
14,84 Kb
C_Customer
480.000
655
299,84 Mb
C_History
480.000
46
21,06 Mb
C_New_Order
144.000
8
1,10 Mb
C_Order
480.000
24
10,99 Mb
4.800.000
54
274,19 Mb
100.000
82
7,82 Mb
1.600.000
306
466,92 Mb
C_Warehouse
C_District
C_Order_Line
C_Item
C_Stock
La seconda fase del progetto ha previsto, attraverso l‟utilizzo del software
“Benchmark Factory for Databases”, l‟esecuzione da parte di un numero
crescente di utenti di un mix pesato di query TPC/C e il conseguente
rilevamento dei tempi di risposta del sistema.
Le query TPC/C, per come è stato definito lo standard, sono:
82
1. New-order, ovvero l‟inserimento di un nuovo ordine da parte di un
cliente. Questa query, statisticamente, viene richiesta con una
frequenza del 45%;
2. Payment, ovvero l‟aggiornamento del saldo di un cliente a seguito
di un pagamento. La frequenza di questa query è pari al 43%;
3. Delivery: aggiornamento dati relativi alla consegna di un ordine.
La frequenza di questa query è pari al 4%;
4. Order-status: recupera lo stato degli ordini più recenti di un
cliente. La frequenza di questa query è pari al 4%;
5. Stock-level: monitoraggio dell‟inventario di una magazzino. La
frequenza di questa query è pari al 4%.
4.4. I RISULTATI: ANALISI SINTETICA
I dati raccolti e rielaborati dai vari test, in seguito alle opportune
modifiche della struttura del database, riguardano i seguenti casi:
 Sistema InnoDB Indicizzato;
 Sistema MyISAM Indicizzato;
 Sistema InnoDB Non Indicizzato;
 Sistema MyISAM Non Indicizzato.
Il ciclo di test, della durata media di un‟ora e mezza ciascuno, ha fornito i
risultati che seguono.
83
4.4.1. QUERY PER SECONDO
Utenti
1
2
4
6
8
10
12
14
16
18
20
22
24
InnoDB Ind.
0,05
0,09
0,22
0,31
0,43
0,53
0,65
0,72
0,83
0,9
1,01
1,11
1,2
MyISAM Ind.
0,05
0,09
0,22
0,32
0,44
0,53
0,64
0,73
0,84
0,9
1,03
1,1
1,2
InnoDB Non Ind.
MyISAM Non Ind.
0
0,01
0
0,01
0
0
0,01
0
0
0
0
0,01
0,01
0,05
0,07
0,13
0,11
0,12
0,14
0,09
0,27
0,08
0,03
0,12
0,04
0,04
Tabella 4.4.1: Query per secondo all‟aumento del numero di utenti connessi al database.
Grafico 4.4.1: Grafico basato sui dati della tabella 4.4.1.
84
Dal grafico e dai valori trovati si ci rende conto che il numero di query per
secondo eseguite dal sistema dipende prevalentemente dalla presenza o
assenza degli indici piuttosto che dal sistema di archiviazione dei dati. Mentre
infatti in presenza di indici le prestazioni dei sistemi InnoDB e MyISAM in
media si equivalgono, in caso di sistemi che non fanno utilizzo di indici,
queste si riducono drasticamente. Un altro fattore su cui prestare attenzione è
l‟andamento delle curve. In una struttura TPC/C che utilizza gli indici il
numero di query eseguite in simultanea aumenta proporzionalmente
all‟aumentare degli utenti. Questo garantisce che, l‟aumento delle utenze non
incida negativamente sulle prestazioni del sistema (nel range di utenti
esaminato). Basandosi sui risultati riportati sopra, in caso di utilizzo degli
indici, sarebbe quindi consigliabile l‟utilizzo del sistema InnoDB perché esso,
grazie alle transazioni, garantisce l‟integrità referenziale dei dati.
4.4.2. BYTE PER SECONDO
Utenti
1
2
4
6
8
10
12
14
16
18
20
22
24
InnoDB Ind.
128,48
133,42
440,62
628,22
779,22
1.038,27
1.304,68
1.292,76
1.525,88
1.829,44
1.950,58
2.122,51
2.417,85
MyISAM Ind.
127,49
134,27
429,62
623,73
797,06
1.017,3
1.289,98
1.308,38
1.554,82
1.848,03
2.047,74
2.110,86
2.296,82
InnoDB Non Ind.
MyISAM Non Ind.
0,15
2,98
11,81
14,04
11,96
0
10,55
0,25
0
0,2
0,02
9,33
0,02
73,76
97,65
167,76
253,77
278,81
291,02
207,2
327,41
200,07
73,51
104,73
58,46
83,97
Tabella 4.4.2: Byte per secondo all‟aumento del numero di utenti connessi al database.
85
Grafico 4.4.2: Grafico basato sui dati della tabella 4.4.2.
Essendo il numero di byte gestiti dal database legato alle query eseguite, il
grafico ottenuto e le considerazioni coincidono, inevitabilmente, con quelle
del paragrafo precedente.
4.4.3. TEMPI DI RISPOSTA MINIMI
Utenti
1
2
InnoDB Ind.
0,027
0,027
MyISAM Ind.
0,003
0,003
86
InnoDB Non Ind.
MyISAM Non Ind.
258,177
40,232
0,534
0,529
4
6
8
10
12
14
16
18
20
22
24
0,018
0,006
0,027
0,006
0,003
0,003
0,003
0,003
0,003
0,004
0,003
0,002
0,002
0,002
0,002
0,002
0,002
0,002
0,002
0,002
0,002
0,002
318,651
57,774
308,994
96,131
40,145
82,105
72,255
69,155
96,692
Tabella 4.4.3: Tempi di risposta minimi relativi all‟esecuzione delle query.
Grafico 4.4.3: Grafico basato sui dati della tabella 4.4.3.
87
0,514
0,672
0,707
0,691
1,451
0,714
1,261
86,356
0,837
32,108
1,251
Durante l‟analisi dei risultati si ci è resi conto che i tempi di risposta del
DBMS in caso di strutture non indicizzate sono mediamente molto superiori
rispetto a quelli dei sistemi indicizzati. Per questo si è optato per rappresentare
i dati raccolti nei vari casi attraverso un grafico a scale sovrapposte. A sinistra
è espressa la scala dei valori delle strutture indicizzate, a destra la scala dei
valori delle strutture non indicizzate. In relazione ai tempi di risposta la
struttura MyISAM si conferma come più efficiente della struttura InnoDB se il
database non fa ricorso agli indici. Parlando invece di strutture indicizzate,
all‟aumento del numero di utenze, la differenza tra i tempi di risposta InnoDB
e quelli MyISAM si riduce fino quasi a coincidere. InnoDB indicizzato
potrebbe rappresentare, per questo, la soluzione migliore riguardo i tempi
minimi di risposta del DBMS per via delle sue funzionalità aggiuntive.
4.4.4. TEMPI DI RISPOSTA MASSIMI
Utenti
1
2
4
6
8
10
12
14
16
18
20
22
24
InnoDB Ind.
0,605
0,41
0,91
0,473
0,315
0,956
2,029
0,389
0,308
1,653
0,284
1,501
0,243
MyISAM Ind.
0,028
0,027
0,051
0,067
0,079
0,074
0,107
0,153
0,158
0,196
0,187
0,832
0,246
InnoDB Non Ind.
MyISAM Non Ind.
258,177
40,232
318,651
333,37
308,994
161,137
177,409
40,145
67,393
82,105
72,255
323,143
96,692
29,289
24,176
48,001
66,669
107,231
124,219
183,415
201,387
217,475
162,591
180,325
208,261
181,353
Tabella 4.4.4: Tempi di risposta massimi relativi all‟esecuzione delle query.
88
Grafico 4.4.4: Grafico basato sui dati della tabella 4.4.4.
Per quanto riguarda i tempi di risposta massimi, i dati in nostro possesso non
ci permettono di definire in maniera sicura quale dei due sistemi di
memorizzazione sia più efficacie in assoluto. Viene comunque ribadita la
profonda differenza tra strutture che utilizzano gli indici e quelle che non li
utilizzano. Dai dati emersi la struttura MyISAM indicizzata rimane comunque
la più veloce. Se questa velocità implica una migliore prestazione o meno del
database non è però possibile stabilirlo senza fare delle supposizioni
89
aggiuntive sui dati del database quali l‟importanza dell‟integrità referenziale
dei dati e la percentuale di errori che si verificano nel sistema.
4.5. I RISULTATI: ANALISI ANALITICA
Mentre i risultati riportati nel paragrafo precedente rappresentavano le
prestazioni del sistema in linea generica, di seguito vengono analizzati i
risultati dei test TPC/C relativi alle singole query.
4.5.1. TEMPI DI ESECUZIONE NEW-ORDER
Utenti
1
2
4
6
8
10
12
14
16
18
20
22
24
InnoDB Ind.
463
327
274
184
170
166
140
133
135
144
165
150
156
MyISAM Ind.
23
18
22
26
21
27
37
44
40
46
46
59
44
InnoDB Non Ind.
MyISAM Non Ind.
206.766
298.347
318.651
333.370
308.994
246.973
177.409
198.236
207.983
239.421
273.916
323.143
352.764
19.200
15.068
24.243
42.055
62.341
73.617
118.605
128.535
148.893
133.869
139.856
187.355
152.551
Tabella 4.5.1: Tempi di esecuzione della query New-Order.
90
Grafico 4.5.1: Grafico basato sui dati della tabella 4.5.1.
91
Eccetto per il sistema InnoDB Indicizzato, dal grafico e dai valori ottenuti dai
test, si ci rende conto che, l‟aumento del numero di utenti, corrisponde a un
aumento del tempo necessario all‟esecuzione di questa query. Nel range di
utenti analizzati è evidente che la struttura MyISAM indicizzata è quella che
esegue la query più velocemente. Se si ci basa sull‟andamento dei grafici,
tuttavia, si può presumere che, con l‟aumento del numero di utenti, la velocità
di InnoDB (grafico logaritmico decrescente) arriverà a superare quella di
MyISAM (grafico lineare crescente) rendendolo quindi il sistema dalle
prestazioni migliori in assoluto. Per quanto riguarda le strutture non
indicizzate bisogna invece valutare se la velocità di MyISAM compensi la sua
mancanza di integrità referenziale.
4.5.2. TEMPI DI ESECUZIONE PAYMENT
Utenti
1
2
4
6
8
10
12
14
16
18
20
22
24
InnoDB Ind.
MyISAM Ind.
95
69
51
83
60
104
57
52
43
45
83
76
71
3
3
3
3
3
3
3
3
3
3
3
3
3
InnoDB Non Ind.
MyISAM Non Ind.
37.953
40.232
46.123
57.774
63.259
74.361
96.131
103.241
126.487
164.382
187.693
204.972
223.459
924
993
1.120
1.257
1.236
1.185
1.451
1.230
2.272
2.483
837
1.059
1.341
Tabella 4.5.2: Tempi di esecuzione della query Payment.
92
Grafico 4.5.2: Grafico basato sui dati della tabella 4.5.2.
93
Nel range selezionato questa query ha tempi di risposta migliori quando la
struttura si basa sul sistema di archiviazione MyISAM. Mantenere l‟integrità
referenziale dei dati attraverso InnoDB, in questo caso comporta un caro
prezzo in termini di tempi di esecuzione. Da notare che l‟uso degli indici
abbatte comunque notevolmente tali tempi.
4.5.3. TEMPI DI ESECUZIONE DELIVERY
Utenti
1
2
4
6
8
10
12
14
16
18
20
22
24
InnoDB Ind.
356
311
282
833
241
291
300
277
442
485
283
249
359
MyISAM Ind.
38
40
40
40
38
39
41
41
41
41
41
41
41
InnoDB Non Ind.
MyISAM Non Ind.
258.177
208.150
227.345
258.230
236.127
253.761
259.435
209.493
254.647
222.750
270.103
291.429
288.238
26.187
26.354
23.702
29.520
29.131
29.840
30.813
30.868
30.875
30.872
31.350
32.108
32.236
Tabella 4.5.3: Tempi di esecuzione della query Delivery.
94
Grafico 4.5.3: Grafico basato sui dati della tabella 4.5.3.
95
In base ai dati ottenuti dai test nel range di utenze simultanee su cui sono stati
effettuati, con MyISAM la query richiede un tempo quasi costante di
esecuzione decisamente inferiore ai tempi richiesti dal database con sistema di
archiviazione InnoDB che, invece, presenta valori oscillanti e, in media, dieci
volte superiori rispetto ai valori MyISAM.
4.5.4. TEMPI DI ESECUZIONE ORDER-STATUS
Utenti
1
2
4
6
8
10
12
14
16
18
20
22
24
InnoDB Ind.
92
99
103
145
162
104
104
98
157
136
130
110
150
MyISAM Ind.
14
16
16
16
17
15
15
15
14
14
15
15
15
InnoDB Non Ind.
MyISAM Non Ind.
23.464
20.031
26.128
29.465
31.872
25.029
22.106
40.145
59.346
82.105
79.625
70.497
83.051
1.810
1.789
1.793
1.790
1.785
1.796
1.789
1.781
1.773
1.798
1.782
1.797
1.789
Tabella 4.5.4: Tempi di esecuzione della query Order-Status.
96
Grafico 4.5.4: Grafico basato sui dati della tabella 4.5.4.
97
L‟andamento di questa query rispecchia quello delle query precedenti. Unica
considerazione aggiuntiva consiste nell‟evidenziare che l‟uso di InnoDB senza
indici porta ad un incremento più veloce dei tempi di esecuzione della query
rispetto ad InnoDB indicizzato.
4.5.5. TEMPI DI ESECUZIONE STOCK-LEVEL
Utenti
1
2
4
6
8
10
12
14
16
18
20
22
24
InnoDB Ind.
7
9
224
5
5
828
379
3
3
588
4
3
4
MyISAM Ind.
4
4
5
4
4
5
4
4
4
11
5
5
5
InnoDB Non Ind.
MyISAM Non Ind.
36885
33467
39579
42931
45353
38525
35617
53671
71887
85661
72255
69155
96692
1785
1779
1798
1810
1820
1846
1854
1861
1868
1908
1907
1937
1944
Tabella 4.5.5: Tempi di esecuzione della query Stock-Level.
98
Grafico 4.5.5: Grafico basato sui dati della tabella 4.5.5.
99
Analizzando i valori raccolti dai test e il grafico da essi ottenuto, si nota che,
con qualche eccezione, le strutture indicizzate richiedono, tra loro, lo stesso
tempo d‟esecuzione. I dati ottenuti dal test del sistema di archiviazione
InnoDB presentano però picchi di tempo che si avvicinano alle tempistiche
legate alla struttura MyISAM Non Indicizzata. Bisogna quindi valutare se il
rischio di incorrere in questi picchi (30% di possibilità) valga l‟utilizzo di una
struttura che garantisca l‟integrità referenziale dei dati in essa contenuti.
4.6. CONCLUSIONI
Dall‟analisi fatta possiamo concludere che, quando utilizziamo strutture
indicizzate, la soluzione migliore sul database è InnoDB perché, anche se i
tempi di risposta a volte sono leggermente più alti di quelli ottenuti della
struttura MyISAM, supporta le chiavi esterne e l‟esecuzione delle query
tramite transazioni. L‟importanza dell‟integrità referenziale dei dati
compensa abbondantemente i ritardi riscontrati. Quando invece si
utilizzano strutture non indicizzate la differenza tra le prestazioni InnoDB
e MyISAM sale vertiginosamente. InnoDB presenta tempi di risposta dieci
volte superiori a quelli di MyISAM. Per stabilire quale delle strutture non
indicizzate conviene utilizzare l‟amministratore dovrà quindi valutare
attentamente se le proprietà aggiuntive di InnoDB valgano o meno il suo
costo supplementare.
100
In realtà i valori dei dati raccolti sono un esempio di come la gestione e il
tuning di una base di dati dipenda da una serie di scelte motivate. Non è
possibile definire una struttura migliore dell‟altra in assoluto o dire che
l‟uso degli indici è la soluzione ideale. Ogni aspetto analizzato, ha i suoi
pro e i suoi contro. Ogni soluzione può essere perfetta per un contesto e
completamente sbagliata per gli altri.
Queste considerazioni, che richiamano i principi fondamentali del tuning,
ci invitano ad approfondire ulteriormente questa tematica e a riflettere
sulla sua importanza in un mondo dove l‟informazione assume un ruolo
sempre più rilevante sia in campo informatico che sociale.
101
BIBLIOGRAFIA
 DENNIS SHASHA (1992): “Database Tuning - A Principled Approach”,
Prentice-Hall
 DENNIS SHASHA E PHILIPPE BONNET (2003): “Database Tuning:
Principles, Experiments, and Troubleshooting Techniques”, Morgan
Kaufman
 SITANSU S. MITTRA (2002): “Database Performance Tuning and
Optimization”, Springer Verlag
 MICHAEL J. COREY, MICHAEL ABBEY, DANIEL J. DECHICHIO (2003):
“Oracle Database: Performance Tuning Guide”, Oracle Press
 IBM (2008): “Tuning Database Performance”, IBM
 ATZENI, CERI, PARABOSCHI, TORLONE (2002): “Basi di dati, Modelli e
linguaggi di interrogazione”, McGraw-Hill
 LOREDANA VIGLIANO (2009): Set di Slide “Basi di Dati”, Università di
Roma.
102
 ANTONELLA POGGI (2003): Set di Slide “Strutture Fisiche di Accesso”,
Università “La Sapienza” di Roma
 MARCO PATELLA (2011): Set di Slide “Strutture di Indicizzazione”,
Università di Bologna
 DENNIS SHASHA (1996): Articolo “Tuning Databases for High
Performance”, ACM Computing Surveys, Vol. 28, No. 1, March 1996
 JULIAN STUHLER (2010), Articolo “A Perspective on Database
Performance Tuning”, Database Journal 16 Aprile 2010
 http://www.databasetuning.org/, DENNIS SHASHA, “Database Tuning”
consultato il 14/08/2011
 http://www.databasetuning.org/, [email protected], “Ottimizzazione
e tuning” consultato il 14/08/2011
 http://it.wikipedia.org/wiki/RAID,
consultato il 14/08/2011
103
Autore
Sconosciuto,
“RAID”