Discussione:
int - bigint e velocità
(troppo vecchio per rispondere)
LsK_Lele
2006-02-02 09:26:41 UTC
Permalink
Ciao,

sto sviluppando un'applicativo che deve loggare ogni minima azione degli
utenti, i record andranno inseriti in una tabella che ha un campo
contatore di tipo int. E' plausibile pensare che questa tabella possa
raggiungere il limite di 2 miliardi e passa imposto dai tipi di dati
int, così avevo pensato di impostare il contatore a bigint. Mi chiedo
però se ci sia un calo di prestazioni nelle query, dato che tempo fa mi
pareva di aver letto qualcosa di simile sull'utilizzo di integer-long in
access...

Inoltre vorrei sapere se c'è qualche sistema per "compattare" i
database, considerando che questi record sono correlati ad altre tabelle
proprio sul campo int, quindi, se dovesse cambiare il valore ID della
tabella dei log, dovrei aggiornare le tabelle correlate ecc ecc...


Grazie e ciao!
size
2006-02-02 09:30:18 UTC
Permalink
ANALISI
Quali operazione devo tenere traccia? Insert, Update (le delete io non le
uso MAI) Spero che le select non vengano loggate....
Quante operazioni averranno?
Per quanto Tempo devo tenere disponibile il tracciato nel tempo? Ha senso
tenere traccia del mese precedente? E dell'anno scorso?


Ciao
LsK_Lele
2006-02-02 13:45:24 UTC
Permalink
Post by size
ANALISI
Quali operazione devo tenere traccia? Insert, Update (le delete io non le
uso MAI) Spero che le select non vengano loggate....
Quante operazioni averranno?
Per quanto Tempo devo tenere disponibile il tracciato nel tempo? Ha senso
tenere traccia del mese precedente? E dell'anno scorso?
Ciao,

effettivamente non sono stato molto chiaro: si tratta di un'applicativo
web, mi serve ottenere un history di ogni utente, con ogni pagina vista
per sessione, tempo trascorso su ogni pagina ecc ecc...

Il tempo è praticamente da non considerare: se un cliente dovesse
chiedermi "mi servono i log degli ultimi 18 mesi" non posso certo
rispondere "li ho cancellati"... ;-)

Ciao!
Luca Bianchi
2006-02-02 09:52:33 UTC
Permalink
Post by LsK_Lele
Ciao,
sto sviluppando un'applicativo che deve loggare ogni minima azione
degli utenti, i record andranno inseriti in una tabella che ha un
campo contatore di tipo int. E' plausibile pensare che questa tabella
possa raggiungere il limite di 2 miliardi e passa imposto dai tipi di
dati int,
...stai considerando soli i valori positivi. In realtà il datatype INT va
da -2 mld (e passa) a + 2mld (e passa). Quindi oltre 4 mld di valori
Post by LsK_Lele
così avevo pensato di impostare il contatore a bigint. Mi
chiedo però se ci sia un calo di prestazioni nelle query, dato che
tempo fa mi pareva di aver letto qualcosa di simile sull'utilizzo di
integer-long in access...
Ogni datatype ha una sua occupazione in termini di spazio. Più il valore è
compatto e tanto più sarà possibile stipare un maggior numero di
informazioni in uno spazio minore. Immagina ad esempio una tabella formata
da 3 campi INT, ovvero 3 x 4 = 12 byte. In questo scenario in una pagina
dati (8060 byte) potranno trovare posto 8060 / 12 = 671 record (ignoriamo
per ora la frammentazione). Con 671 record per pagina, per stipare 1 mld di
record hai bisogno di 1.490.313 pagine. Modificando uno dei 3 INT in BIGINT
(8 byte) ogni pagina potrà stipare al massimo 503 record e, pertanto, per lo
stesso numero di record (1 mld) servono ora 1.988.072 pagine. Questo
incremento ha un costo non solo in termini di spazio occupato ma anche in
termini di performance visto che un eventuale table scan deve sorbirsi il
33% di pagine in più.
Ovviamente la tua speranza è riposta nel fatto che le ricerche saranno
mirate e quindi, tendenzialmente, supportate da un indice. E' altrettanto
vero, però, che anche la chiave di indice più compatta permette di stipare
in una medesima pagina un numero superiore di puntatori e, quindi, è lecito
attendersi, con numeri del genere, in una riduzione del numero dei livelli
b-tree da attraversare per raggiungere i dati potendo contare su una chiave
di dimensioni più compatte.
Quale usare allora? Beh, la domanda dipende da "cosa ti serve". Se hai
necessità di memorizzare fino a 4 mld di valori differenti di sicuro un INT;
se l'int non è più sufficiente c'è ben poco da scegliere...
Post by LsK_Lele
Inoltre vorrei sapere se c'è qualche sistema per "compattare" i
database, considerando che questi record sono correlati ad altre
tabelle proprio sul campo int, quindi, se dovesse cambiare il valore
ID della tabella dei log, dovrei aggiornare le tabelle correlate ecc
ecc...
Talvolta mi capita di sentire affermazioni del genere (anche in questo ng),
ma ancora nessuno ha mai dato una motivazione (sensata) per alterare un
valore ID. Il fatto di "compattare i valori" per eliminare i "buchi" non è
una valida argomentazione...
Post by LsK_Lele
Grazie e ciao!
Bye
--
Luca Bianchi
Microsoft MVP - SQL Server
http://mvp.support.microsoft.com
LsK_Lele
2006-02-02 13:50:20 UTC
Permalink
Post by Luca Bianchi
...stai considerando soli i valori positivi. In realtà il datatype INT va
da -2 mld (e passa) a + 2mld (e passa). Quindi oltre 4 mld di valori
Giusto, non ho tenuto conto dei negativi...
Comunque siamo al punto di partenza: anche 4 mld non sono impossibili da
raggiungere...
Post by Luca Bianchi
[CUT]
Quale usare allora? Beh, la domanda dipende da "cosa ti serve". Se hai
necessità di memorizzare fino a 4 mld di valori differenti di sicuro un INT;
se l'int non è più sufficiente c'è ben poco da scegliere...
Chiarissimo, grazie mille!
Post by Luca Bianchi
Post by LsK_Lele
Inoltre vorrei sapere se c'è qualche sistema per "compattare" i
database, considerando che questi record sono correlati ad altre
tabelle proprio sul campo int, quindi, se dovesse cambiare il valore
ID della tabella dei log, dovrei aggiornare le tabelle correlate ecc
ecc...
Talvolta mi capita di sentire affermazioni del genere (anche in questo ng),
ma ancora nessuno ha mai dato una motivazione (sensata) per alterare un
valore ID. Il fatto di "compattare i valori" per eliminare i "buchi" non è
una valida argomentazione...
Supponiamo che riuscissi a liberarmi dei log "vecchi" (possibilità
alquanto remota), mi troverei con una tabella con, ad esempio, ultimo ID
= 4.000.000.000 e 1 mld di record in totale. Avrei praticamente 3mld
"liberi" da poteri riutilizzare se potessi "compattare" il DB invece di
spostarmi sui bigint col calo di prestazioni che tu stesso mi hai
descritto sopra...
Come mai non ti sembra una valida argomentazione?

Grazie ancora e ciao!
Luca Bianchi
2006-02-02 13:56:57 UTC
Permalink
Post by LsK_Lele
Supponiamo che riuscissi a liberarmi dei log "vecchi" (possibilità
alquanto remota), mi troverei con una tabella con, ad esempio, ultimo
ID = 4.000.000.000 e 1 mld di record in totale. Avrei praticamente
3mld "liberi" da poteri riutilizzare se potessi "compattare" il DB
invece di spostarmi sui bigint col calo di prestazioni che tu stesso
mi hai descritto sopra...
Come mai non ti sembra una valida argomentazione?
Hai fatto stato anche tu delle difficoltà che comporta modificare un valore
pk... ;-)
Cambiando il valore della pk viene meno il requisito di univocità che la pk
stessa dovrebbe soddisfare e soprattutto laddove produci dei documenti con
valenza esterna (ma non solo) sulla base di una pk (numero di fattura,
numero di protocollo, numero d'ordine, targa automobilistica, numero di
telaio di un veicolo, codice fiscale e tanto tanto altro) puoi avere delle
ripercussioni che vanno ad impattare soggetti terzi.
Se fai riferimento al record 123456 dovrai iniziare a chiederti "quale
123456? Quello attuale o quello precedente?" Ecco li che il singolo valore
non è più in grado di identificare univocamente un record ma dovrai
aggiungere un ulteriore qualificatore e quindi avrai il record 123456 del
2006, quello del 2005 e così via. Un record 123456 per ogni "evento di
compattazione"...
Post by LsK_Lele
Grazie ancora e ciao!
Bye
--
Luca Bianchi
Microsoft MVP - SQL Server
http://mvp.support.microsoft.com
LsK_Lele
2006-02-02 14:55:00 UTC
Permalink
Post by Luca Bianchi
Cambiando il valore della pk viene meno il requisito di univocità che la pk
stessa dovrebbe soddisfare e soprattutto laddove produci dei documenti con
valenza esterna (ma non solo) sulla base di una pk (numero di fattura,
numero di protocollo, numero d'ordine, targa automobilistica, numero di
telaio di un veicolo, codice fiscale e tanto tanto altro) puoi avere delle
ripercussioni che vanno ad impattare soggetti terzi.
Se fai riferimento al record 123456 dovrai iniziare a chiederti "quale
123456? Quello attuale o quello precedente?" Ecco li che il singolo valore
non è più in grado di identificare univocamente un record ma dovrai
aggiungere un ulteriore qualificatore e quindi avrai il record 123456 del
2006, quello del 2005 e così via. Un record 123456 per ogni "evento di
compattazione"...
Io avevo immaginato una soluzione di questo tipo:
creo un nuovo db con struttura identica a quello da compattare.
per ogni record di Tabella1 nel DB vecchio faccio una insert nella
Tabella1 del db nuovo.
Fatta la insert mi becco il nuovo ID, estrapolo tutti i record di
Tabella2 (correlata a Tabella1 sul campo ID) riferiti al record del
vecchio DB e li inserisco nel nuovo DB, referenziandoli al nuovo ID e
così via...

Non ho però idea di quanto tempo necessiti un'operazione del genere,
considerando il numero di record e di tabelle correlate...

Ciao!
size
2006-02-02 14:01:44 UTC
Permalink
Se ti metti a fare il log di tutte le select ti serve un server grande come
milano per gestire lo spazio. Anche la stessa telecom non tiene per sempre
il dettaglio delle telefonate.
Comunque puoi usare più campi per rendere univoca una riga, quindi aumenti
le possibilità.

Buona spesa per gli hard disk dei log
LsK_Lele
2006-02-02 14:55:41 UTC
Permalink
Post by size
Se ti metti a fare il log di tutte le select ti serve un server grande come
milano per gestire lo spazio. Anche la stessa telecom non tiene per sempre
il dettaglio delle telefonate.
Comunque puoi usare più campi per rendere univoca una riga, quindi aumenti
le possibilità.
Buona spesa per gli hard disk dei log
Non mi sono spiegato di nuovo: devo tener traccia delle pagine
visualizzate, non di ogni singola select, update, delete ecc... ;-)
Loading...