Questa pagina è stata tradotta automaticamente. Leggi l'originale in inglese. English

Libreria IBSurgeon

Le differenze tra i campi VARCHAR e INTEGER nelle chiavi

Uso ID interi come chiavi primarie nelle mie tabelle. E se invece usassi campi varchar? Perderò prestazioni in quel caso, soprattutto per tabelle grandi? Le join funzioneranno ancora velocemente come con la colonna intera?

Le tue prestazioni dovrebbero essere più o meno le stesse con varchar o interi. Firebird confronta sempre le chiavi degli indici byte per byte e viene memorizzata solo la parte significativa del valore.

Una chiave a campo singolo viene prima convertita in uno dei tre tipi canonici: stringa con collation, doppia precisione e (purtroppo) intero a 64 bit. Le date diventano numeri a virgola mobile a doppia precisione.

Le stringhe che hanno una collation diversa dal loro valore byte vengono convertite nel loro formato di collation. È una sorta di arte nera che espande la dimensione della stringa, ma il risultato è che la stringa trova la sua posizione corretta quando viene ordinata con altre stringhe della stessa collation. ‘A’, ‘a’, ‘â’, ‘á’, ‘Ă’, ‘ã’, ‘ä’, ‘å’, ‘ă’, ‘ą’, ‘Ā’ appaiono tutti nei loro posti designati. (Scusa per quello che ha fatto al tuo client di posta… nel mio, sono undici varianti di ‘A’.) Gli spazi finali non sono inclusi nella chiave.

Il numero a doppia precisione viene alterato così che anche lui si ordini byte per byte - approssimativamente invertendo il segno, poi l’esponente, poi la mantissa, troncando gli zeri finali.

A seconda dell’endianness degli interi a 64 bit sul computer, anche loro vengono alterati per confrontarsi byte per byte. Può sembrare una de-ottimizzazione, ma le chiavi degli indici non sono memorizzate su confini naturali e subiscono compressione del prefisso, quindi non c’è modo di usare un confronto più grande di byte per byte.

Le chiavi composte sono più o meno le stesse. Ogni parte viene convertita nel suo tipo di chiave indice e riempita a un multiplo di 4 byte. Dopo ogni quattro byte, Firebird aggiunge un byte con la posizione del campo corrente della chiave. Così un indice su Cognome, Nome, SegnoZodiacale verrebbe fuori come 1Harr1ison2Ann 3Gemi3ni. Questo evita l’imbarazzo di confondere Damnation con Dam nation.

Perché ho detto “(purtroppo)” sopra? Perché avere un formato unico per i numeri permette a Firebird di cambiare la dimensione dei numeri senza ricreare gli indici su di essi. Ma quando Borland aggiunse gli interi a 64 bit - InterBase aveva interi a 64 bit fin dall’inizio sui Vax - qualche mente brillante si rese conto che la doppia precisione ha 56 bit di precisione e gli interi a 64 bit ne hanno 64. D’altra parte, gli indici di Firebird sono progettati per gestire una certa imprecisione… o gli 8 bit rimanenti potrebbero essere attaccati alla fine… comunque. Quindi devi ricostruire gli indici quando passi da Numeric/Decimal 9 a Numeric/Decimal 12. Triste.

“Compressione del prefisso?” Quando si memorizza una chiave diversa dalla prima su una pagina o dalla prima dopo un salto sulla pagina, Firebird guarda la chiave precedente e tronca quella parte dell’inizio della chiave successiva che duplica il suo predecessore e attacca la lunghezza della parte troncata all’inizio. Così le stringhe “AAAA”, “AAAB”, “AAAC”, “AABC” diventano

“AAAA”, “3B”, “3C” e “2BC”. C’è un problema con alcuni formati di GUID che mettono la parte volatile del numero per prima, seguita dalla parte fissa. Questo vanifica la compressione del prefisso e gonfia la dimensione degli indici.

“Salto?” - La compressione del prefisso riduce di molto la dimensione degli indici, riducendo l’I/O, ma richiede la lettura dell’intera pagina per decifrare la chiave. Va bene con pagine da 1K, ma con dimensioni di pagina maggiori il calcolo era inaccettabile. Quindi ogni pagina di indice ora ha un proprio indice che punta agli offset delle voci non compresse. Quell’indice si chiama vettore di salto.

Ann Harrision