Friday, 15 November 2013

Explain MySQL : Key_length

Oggi volevo approfondire  le indicazioni che si possono ricavare dal campo Key_length a seguito di un comando di Explain su una select.

Innanzi tutto la definizione del manuale mysql :

This column shows the number of bytes MySQL will use in the index.


Quindi con questa indicazione posso capire quante colonne di un indice composto sono utilizzate. 


Partiamo dall'esempio del precedente post:


explain  select * from People where last_name = 'ccccc' and first_name = 'vvvvvv' and dob = '1967-03-01';
    +----+-------------+--------+------+---------------+-----------+---------+-------------------+------+-------------+
    | id | select_type | table  | type | possible_keys | key       | key_len | ref               | rows | Extra       |
    +----+-------------+--------+------+---------------+-----------+---------+-------------------+------+-------------+
    |  1 | SIMPLE      | People | ref  | last_name     | last_name | 107     | const,const,const |    1 | Using where |
    +----+-------------+--------+------+---------------+-----------+---------+-------------------+------+-------------+


E riportiamo il DDL della Tabella :

mysql> show create table People\G
*************************** 1. row ***************************

 Table: People
 

Create Table: CREATE TABLE `People` (
  `last_name` varchar(50) NOT NULL,
  `first_name` varchar(50) NOT NULL,
  `dob` date NOT NULL,
  `gender` enum('m','f') NOT NULL,
  KEY `last_name` (`last_name`,`first_name`,`dob`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1



Viene riportata una key_len di 107 bytes cosi composta :

Index(`last_name`,`first_name`,`dob`) = last_name varchar(50) + 2 (length-bytes) + first_name varchar(50) +2 (length-bytes) = 104 bytes + dob (date) (3 byte) = 107 bytes.

L'indice usa tutte le colonne dell'indice. 

Ora se per i campi date, INT, ecc l'occupazione in bytes è ben definita nelle relative tabelle del manuale mysql 

SMALLINT:  Storage Size :    2 bytes 
INT:           Storage Size :    4 bytes
DATE :        Storage Size :    3 bytes

La stessa cosa non si può dire con i campi char() o varchar(). La key_len dipende infatti anche dal character set scelto.

Nel caso di della tabella People il character set è il "latin1" che per ogni carattere occupa 1 bytes.

Ma nel caso del character set utf8 sia passa da 1 bytes a 3 bytes per carattere.

Vediamo un esempio : character set = utf8


CREATE TABLE table1 (campo1 char(3) NOT NULL, campo2 int(11) NOT NULL,campo3 char(1) NOT NULL, PRIMARY KEY (campo1,campo2,campo3) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ; 

EXPLAIN SELECT a FROM t WHERE a='sak' AND b = 112;
        +----+-------------+-------+------+---------------+---------+---------+-------------+------+--------------------------+
        | id | select_type | table | type | possible_keys | key     | key_len | ref         | rows | Extra                    |
        +----+-------------+-------+------+---------------+---------+---------+-------------+------+--------------------------+
        |  1 | SIMPLE      | t     | ref  | PRIMARY       | PRIMARY | 13      | const,const |    4 | Using where; Using index |
        +----+-------------+-------+------+---------------+---------+---------+-------------+------+--------------------------+



Volutamente utilizzo solo 2 colonne dell'indice composto da 3 colonne e la key_len avrà un valore di 13 e sarà questa volta cosi composta :

9 bytes cosi calcolati : campo1 (char(3)) x 3 bytes (utf8) = 9 a questo aggiungo + 4 bytes INT datatype = 13 bytes.


Alla prossima.


Ciaoaoaoaao




No comments:

Post a Comment