Mysql
 sql >> Database >  >> RDS >> Mysql

Prestazioni MySQL BIGINT(20) vs Varchar(31).

Questo dovrebbe davvero essere misurato, possiamo fare alcune "ipotesi" sulla base di ciò che sappiamo e di ciò che assumiamo, ma quelle sono solo ipotesi.

Non dici se questa tabella è InnoDB o MyISAM con righe dinamiche o MyISAM con righe a lunghezza fissa. Questo farà una certa differenza.

Ma per valori come quello che hai pubblicato, '961637593864109_412954765521130' (31 caratteri), supponendo che tu stia utilizzando un set di caratteri a byte singolo (es. latin1) o un set di caratteri che codifica quei caratteri particolari in un singolo byte (es. utf8)...

Per il formato dinamico InnoDB e MyISAM, sono 31+1-8=24 byte extra per quella riga. (BIGINT può contenere 8 byte, un valore VARCHAR(31) di 31 caratteri utilizzerà 32 byte.)

Per la tabella MyISAM con righe di lunghezza fissa, sarebbe una differenza di 23 byte per riga. (Lo spazio è riservato a tutti i 31 caratteri e la lunghezza non deve essere memorizzata.)

Il valore della chiave primaria verrà ripetuto anche in ogni indice, quindi c'è anche più spazio per ogni indice.

Supponendo che le righe della tabella siano 120 byte utilizzando BIGINT e le righe siano 144 byte con VARCHAR, è un 20% aumento. Più grandi sono le righe, minore è l'aumento percentuale e viceversa.

Per 1.000.000 di righe (voglio così dire "una riga meelyun" nello stesso modo in cui il dottor Evil mette il mignolo all'angolo di questa bocca e dice "un milione di dollari") quei 24 byte extra per riga ammontano a circa 24 MB.

Ma non è proprio così facile. In termini di spazio InnoDB, è una questione di come le righe possono "adattarsi" a un blocco. Maggiore è la dimensione media della riga, maggiore sarà la quantità di spazio libero in un blocco.

Se non fai nulla con le righe se non archiviarle su disco, in realtà è solo un aumento dello spazio su disco e tempo e spazio extra per i backup.

Se lo stesso numero di righe "144 byte" rientra in un blocco come righe "120 byte", non vedrai alcuna differenza nello spazio. Ma se un blocco contiene meno righe, significa più blocchi, più spazio nel pool di buffer InnoDB, più i/o, ecc.

Per le query su una singola riga, in base al valore della chiave primaria o in qualche altra ricerca univoca nell'indice, la differenza sarà trascurabile.

Se hai a che fare con set di risultati più grandi, si tratta di memoria extra per preparare il set di risultati e byte extra da trasferire al client, ecc.

Se la chiave VARCHAR è progettata in modo tale che i "gruppi" di righe a cui si accede insieme abbiano la stessa parte iniziale del valore della chiave, con InnoDB potrebbe effettivamente esserci un miglioramento delle prestazioni. Questo perché la chiave primaria è la chiave del cluster... è molto più probabile che le righe necessarie per soddisfare una query si trovino nello stesso blocco, piuttosto che essere distribuite su un gruppo di blocchi.

Al contrario, se vengono eseguiti inserimenti ed eliminazioni, ci sarà più spazio libero in alcuni blocchi. (Con le eliminazioni, lo spazio per le righe eliminate rimane nel blocco; per riutilizzarlo, è necessario inserire una riga con lo stesso valore chiave (o almeno un valore chiave abbastanza vicino da atterrare nello stesso blocco .) E con inserti casuali, otterremo suddivisioni in blocchi.