关于varchar和text的一点点区别

大家都知道varchar(N)当N大于255的时候mysql内部会转成text类型进行存储,所有很多人只要存储的字符串大于255都不加思考的就随便使用,其实这里还有一个区别就是

查询当中是否使用临时表的问题,请看如下测试:

字段说明:

ref   varchar(1000) , org_id int ,id int 

测试语句:

show status like '%tmp%';select id   from ticket group by org_id order by ref limit 1,1 ; show status like '%tmp%';           
+-------------------------+--------+
| Variable_name           | Value  |
+-------------------------+--------+
| Created_tmp_disk_tables | 8      |
| Created_tmp_files             | 6      |
| Created_tmp_tables        | 17     |
| Handler_tmp_update      | 43650  |
| Handler_tmp_write       | 463519 |
| Rows_tmp_read           | 234483 |
+-------------------------+--------+
6 rows in set (0.00 sec)

Empty set (0.14 sec)

+-------------------------+--------+
| Variable_name           | Value  |
+-------------------------+--------+
| Created_tmp_disk_tables | 8      |
| Created_tmp_files             | 6      |
| Created_tmp_tables      | 18     |
| Handler_tmp_update      | 43650  |
| Handler_tmp_write       | 463520 |
| Rows_tmp_read           | 234491 |
+-------------------------+--------+
6 rows in set (0.00 sec)

从上面的结果可以看的出来查询产生了内部临时表,但是并没有出现磁盘临时表

现在:修改ref的数据类型为text

alter table ticket modify ref text not null;                      

Query OK, 56337 rows affected (5.96 sec)               
Records: 56337  Duplicates: 0  Warnings: 0

show status like '%tmp%';select id   from ticket group by org_id order by ref limit 1,1 ; show status like '%tmp%';
+-------------------------+--------+
| Variable_name           | Value  |
+-------------------------+--------+
| Created_tmp_disk_tables | 8      |
| Created_tmp_files             | 6      |
| Created_tmp_tables      | 18     |
| Handler_tmp_update      | 43650  |
| Handler_tmp_write       | 463520 |
| Rows_tmp_read           | 234497 |
+-------------------------+--------+
6 rows in set (0.00 sec)

Empty set (0.21 sec)

+-------------------------+--------+
| Variable_name           | Value  |
+-------------------------+--------+
| Created_tmp_disk_tables | 9      |
| Created_tmp_files       | 6      |
| Created_tmp_tables      | 19     |
| Handler_tmp_update      | 43650  |
| Handler_tmp_write       | 463521 |
| Rows_tmp_read           | 234505 |
+-------------------------+--------+
6 rows in set (0.00 sec)

可见产生了磁盘临时表。

现在将ref字段放在select 列列表中 order by 字段 改为id再次进行测试

show status like '%tmp%';select ref   from ticket group by org_id order by id limit 1,1 ; show status like '%tmp%';     
+-------------------------+--------+
| Variable_name           | Value  |
+-------------------------+--------+
| Created_tmp_disk_tables | 9      |
| Created_tmp_files       | 6      |
| Created_tmp_tables      | 19    |
| Handler_tmp_update      | 43650  |
| Handler_tmp_write       | 463521 |
| Rows_tmp_read           | 234511 |
+-------------------------+--------+
6 rows in set (0.00 sec)

Empty set (0.16 sec)

+-------------------------+--------+
| Variable_name           | Value  |
+-------------------------+--------+
| Created_tmp_disk_tables | 10     |
| Created_tmp_files       | 6      |
| Created_tmp_tables      | 20     |
| Handler_tmp_update      | 43650  |
| Handler_tmp_write       | 463522 |
| Rows_tmp_read           | 234519 |
+-------------------------+--------+
6 rows in set (0.00 sec)

再次将ref 改为 varchar(1000) 进行测试

alter table ticket modify ref varchar(1000) not null;                                        

 Query OK, 56337 rows affected (5.84 sec)               
Records: 56337  Duplicates: 0  Warnings: 0

(user:root  time: 15:35)[db: itop1011]show status like '%tmp%';select ref   from ticket group by org_id order by id limit 1,1 ; show status like '%tmp%';
+-------------------------+--------+
| Variable_name           | Value  |
+-------------------------+--------+
| Created_tmp_disk_tables | 10     |
| Created_tmp_files       | 6      |
| Created_tmp_tables      | 20     |
| Handler_tmp_update      | 43650  |
| Handler_tmp_write       | 463522 |
| Rows_tmp_read           | 234525 |
+-------------------------+--------+
6 rows in set (0.00 sec)

Empty set (0.17 sec)

+-------------------------+--------+
| Variable_name           | Value  |
+-------------------------+--------+
| Created_tmp_disk_tables | 10     |
| Created_tmp_files       | 6      |
| Created_tmp_tables      | 21     |
| Handler_tmp_update      | 43650  |
| Handler_tmp_write       | 463523 |
| Rows_tmp_read           | 234533 |
+-------------------------+--------+
6 rows in set (0.00 sec)

产生了内部临时表但是没有产生磁盘临时表

现在将ref字段放在group by后面测试

show status like '%tmp%';select id    from ticket group by ref  order by id limit 10,1 ; show status like '%tmp%';           
+-------------------------+--------+
| Variable_name           | Value  |
+-------------------------+--------+
| Created_tmp_disk_tables | 16     |
| Created_tmp_files       | 6      |
| Created_tmp_tables      | 43     |
| Handler_tmp_update      | 43650  |
| Handler_tmp_write       | 576262 |
| Rows_tmp_read           | 234969 |
+-------------------------+--------+
6 rows in set (0.01 sec)


+------+
| id   |
+------+
| 6302 |
+------+
1 row in set (1.19 sec)


+-------------------------+--------+
| Variable_name           | Value  |
+-------------------------+--------+
| Created_tmp_disk_tables | 17     |
| Created_tmp_files       | 6      |
| Created_tmp_tables      | 44     |
| Handler_tmp_update      | 43650  |
| Handler_tmp_write       | 632599 |
| Rows_tmp_read           | 290990 |
+-------------------------+--------+
6 rows in set (0.00 sec)

依然产生了磁盘临时表。

想必测试到此,已经很清楚说明了两者之间的小区别。

总结:

varchar 长度大于255的时候 一般情况来和text没有啥特别大的区别,但是当查询用到了临时表

(具体mysql如何使用内部临时表可见:http://dev.mysql.com/doc/refman/5.1/en/internal-temporary-tables.html

如果查询列出现了text字段或者order by或group by里出现了text字段,这时就会产生磁盘临时表。

可见在表设计的时候能用varchar还是尽量使用varchar ,特别是text 又不支持默认值(但支持not null 约束)。

ps: 如果想减少Created_tmp_tables 可适当增大tmp_table_size的值,该变量支持动态修改set [global] tmp_table_size = 64*1024*1024

   不过这对磁盘临时表没用。



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
char、varchartext都是用于存储文本数据的数据类型,但它们之间有以下区别: 1. 存储长度:char是固定长度的,varchartext是可变长度的。例如,如果定义一个char(10)类型的字段,那么无论实际存储的数据是多长,都会占用10个字节的存储空间;而如果是varchar(10)或text类型的字段,实际存储的数据长度则会根据数据大小动态调整。 2. 存储空间:由于char是固定长度的,所以它们在存储时会占用更多的存储空间。例如,存储一个长度为5的字符串,char(10)类型需要占用10个字节的存储空间,而varchar(10)或text类型只需要占用6个字节的存储空间。 3. 查询效率:由于char是固定长度的,所以在查询时比varchartext更快。这是因为char的每个字符在存储时都会占用相同的存储空间,所以在查询时可以更快地定位到每个字符的位置。 4. 字符集:char、varchartext都支持各种字符集,但它们之间的区别在于存储的方式不同。char和varchar存储在表中时会根据表的字符集进行编码,而text则是以二进制形式存储的。 综上所述,选择使用char、varchar还是text应该根据实际需求来进行选择。如果需要存储固定长度的文本数据,可以使用char类型;如果需要存储可变长度的文本数据且对存储空间有要求,可以使用varchar类型;如果需要存储大量的文本数据,可以使用text类型。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值