分类: Mysql/postgreSQL
2016-07-01 12:45:52
关于mysql中字符串的类型引用,应该是都不陌生,为什么要写这篇文章,还是想具体看看在不同情况下,这两种字符串在时间和性能上有什么影响。
版本 5.7.12
1、首先创建两个表:
Create Table: CREATE TABLE `t9` (
`name` char(10) DEFAULT NULL,
`id` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
Create Table: CREATE TABLE `t10` (
`name` varchar(10) DEFAULT NULL,
`id` int(10) DEFAULT NULL,
KEY `in_name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
2、然后分别为两个表插入200W的数据,数据格式如下
mysql> select * from t9 limit 1;
+--------------------+------+
| name | id |
+--------------------+------+
| 我们都是孩子 | NULL |
+--------------------+------+
3、然后测试全表扫描
select name,id from t9;
select name,id from t10;
每次查询后,清空一次缓存。
多次后得到结果,
可以看到,时间几乎没有区别。这是什么原因呢?,一直以为都是在说,定长比变长要快。查阅了Inside君的讲解,对于多字节的字符编码,CHAR类型不再代表固定的字符串了,在Innodb存储引擎内部将视为变长字符类型。根据hexdump所看,内部确实有变长字段的存储位。
那么如果有索引的情况呢?
4、为两个表的name字段添加索引
Create Table: CREATE TABLE `t9` (
`name` char(10) DEFAULT NULL,
`id` int(11) DEFAULT NULL,
KEY `n_index` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
然后在来查看,查询速度上有什么差别?
看到t9的char字段确实比t10快了1.5倍。这是为什么呢?
在走索引的情况,来看看他们执行计划:
mysql> explain select name from t9\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: t9
partitions: NULL
type: index
possible_keys: NULL
key: n_index
key_len: 31
ref: NULL
rows: 1994168
filtered: 100.00
Extra: Using index
1 row in set, 1 warning (0.00 sec)
mysql> explain select name from t10\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: t10
partitions: NULL
type: index
possible_keys: NULL
key: in_name
key_len: 33
ref: NULL
rows: 1994168
filtered: 100.00
Extra: Using index
1 row in set, 1 warning (0.00 sec)
可以清楚看到Key_len的不同,这也许就是char和varchar的不同之处了,字段不同,在sending data的时候就要多发送一部分数据,所以导致了时间不同。
结论:在构建表的时候,字段最好都设置not null,另外如果不是每次都需要返回特别多行的时候,varchar是个不错的选择,因为节约空间资源。