類型 | 所占空間 | 不允許為NULL額外占用 |
---|---|---|
char | 一個字符三個字節(jié) | 一個字節(jié) |
varchar | 一個字符三個字節(jié) | 一個字節(jié) |
int | 四個字節(jié) | 一個字節(jié) |
tinyint | 一個字節(jié) | 一個字節(jié) |
測試數(shù)據(jù)表如下:
CREATE TABLE `test_table` ( `id` int(11) NOT NULL AUTO_INCREMENT, `a` int(11) DEFAULT NOT NULL, `b` int(11) DEFAULT NOT NULL, `c` int(11) DEFAULT NOT NULL, PRIMARY KEY (`id`), KEY `test_table_a_b_c_index` (`a`,`b`,`c`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
命中索引:
mysql> explain select * from test_table where a = 1 and b = 2 and c = 3; +----+-------------+------------+------------+------+------------------------+------------------------+---------+-------------------+------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+------------+------------+------+------------------------+------------------------+---------+-------------------+------+----------+-------------+ | 1 | SIMPLE | test_table | NULL | ref | test_table_a_b_c_index | test_table_a_b_c_index | 12 | const,const,const | 1 | 100.00 | Using index | +----+-------------+------------+------------+------+------------------------+------------------------+---------+-------------------+------+----------+-------------+
可以看到 key_len = 12
,這是如何計算的呢?
因為字符集是 UTF8,一個字段占用四個字節(jié),三個字段就是 4 * 3 = 12 字節(jié)。
是否允許為 NULL,如果允許為 NULL,則需要用額外的字節(jié)來標記該字段,不同的數(shù)據(jù)類型所需的字節(jié)大小不同。
mysql> ALTER TABLE `test_table` CHANGE `a` `a` INT(11) NULL; mysql> ALTER TABLE `test_table` CHANGE `c` `c` INT(11) NULL; mysql> ALTER TABLE `test_table` CHANGE `b` `b` INT(11) NULL; mysql> explain select * from test_table where a = 1 and b = 2 and c = 3; +----+-------------+------------+------------+------+------------------------+------------------------+---------+-------------------+------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+------------+------------+------+------------------------+------------------------+---------+-------------------+------+----------+-------------+ | 1 | SIMPLE | test_table | NULL | ref | test_table_a_b_c_index | test_table_a_b_c_index | 15 | const,const,const | 1 | 100.00 | Using index | +----+-------------+------------+------------+------+------------------------+------------------------+---------+-------------------+------+----------+-------------+
可以看到,當字段允許為空時,這時的key_len
變成了15 = 4 3 + 1 3(INT 類型為空時,額外占用一個字節(jié))。
有了這些基礎(chǔ)知識之后,再來根據(jù)實際的SQL 判斷索性性能好壞。
還是以上面那張數(shù)據(jù)表為例,為 a、b、c 三個字段創(chuàng)建聯(lián)合索引。
SQL 語句 | 是否索引 |
---|---|
explain select * from test_table where a = 1 and b = 2 and c = 3; | Extra:Using index key_len: 15 |
explain select * from test_table where a = 1 and b = 2 and c = 3 order by c; | Extra:Using index key_len: 15 |
explain select * from test_table where b = 2 and c = 3; | Extra:Using where; Using index key_len: 15 |
explain select * from test_table where a = 1 order by c; | Extra:Using where; Using index; Using filesort key_len: 5 |
explain select * from test_table order by a, b, c; | Extra:Using index key_len: 15 |
explain select * from test_table order by a, b, c desc; | Extra:Using index; Using filesort key_len:15 |
explain select * from test_table where a in (1,2) and b in (1,2,3) and c = 1; | Extra:Using where; Using index key_len: 15 |
通常在查看執(zhí)行計劃時, Extra 列為 Using index 則表示優(yōu)化器使用了覆蓋索引。
以上就是Mysql 索引該如何設(shè)計與優(yōu)化的詳細內(nèi)容,更多關(guān)于MySQL 索引設(shè)計與優(yōu)化的資料請關(guān)注腳本之家其它相關(guān)文章!