因为CHAR与VARCHAR只能用于存储少量的字符串(1-65535个字符),所以当存储大文本时,就需要用到TEXT或BLOB,其两者的区别在于,TEXT只能保存字符串,而BLOB可以保存二进制数据(多媒体文件),见下表:
类型 | 可存储字节 | 空间占用 |
TINYTEXT/TINYBLOB |
256 bytes | 256bytes |
TEXT/BLOB | 65,535 bytes | 64KB |
MEDIUMTEXT/MEDIUMBLOB | 16,777,215 bytes | 16MB |
LONGTEXT/LONGBLOB | 4,294,967,295 bytes | 4GB |
这两种数据类型在执行删除(尤其是大量删除)时会呈现出一些问题:
删除操作会在表中留下很多的“空洞”,在未来向这些“空洞”内插入数据时会有性能亏损,所以为了提高性能,建议使用optimize table命令对表进行压缩,尽量的消除“空洞"
STEP1:创建数据库
create database test;
STEP2:调用数据库并创建表
create table test(id char(1),testchar text);
STEP3:创建test表
create table test(id char(1),testchar text);
STEP4:向test表中使用repeat函数插入大量字符串,插入1000个Hello
insert into test values(1,repeat('Hello',1000));
insert into test values(2,repeat('Hello',1000));
insert into test values(3,repeat('Hello',1000));
STEP5:反复插入数据,语句意为将整表数据插入表(复制)
insert into test select * from test;
Query OK, 3 rows affected (0.02 sec)
Records: 3 Duplicates: 0 Warnings: 0
insert into test select * from test;
Query OK, 6 rows affected (0.00 sec)
Records: 6 Duplicates: 0 Warnings: 0
insert into test select * from test;
Query OK, 12 rows affected (0.02 sec)
Records: 12 Duplicates: 0 Warnings: 0
insert into test select * from test;
Query OK, 24 rows affected (0.00 sec)
Records: 24 Duplicates: 0 Warnings: 0
insert into test select * from test;
Query OK, 48 rows affected (0.11 sec)
Records: 48 Duplicates: 0 Warnings: 0
insert into test select * from test;
Query OK, 96 rows affected (0.13 sec)
Records: 96 Duplicates: 0 Warnings: 0
insert into test select * from test;
Query OK, 192 rows affected (0.68 sec)
Records: 192 Duplicates: 0 Warnings: 0
insert into test select * from test;
Query OK, 384 rows affected (0.04 sec)
Records: 384 Duplicates: 0 Warnings: 0
insert into test select * from test;
Query OK, 768 rows affected (0.04 sec)
Records: 768 Duplicates: 0 Warnings: 0
insert into test select * from test;
Query OK, 1536 rows affected (0.07 sec)
Records: 1536 Duplicates: 0 Warnings: 0
insert into test select * from test;
Query OK, 3072 rows affected (0.12 sec)
Records: 3072 Duplicates: 0 Warnings: 0
insert into test select * from test;
Query OK, 6144 rows affected (1.81 sec)
Records: 6144 Duplicates: 0 Warnings: 0
insert into test select * from test;
Query OK, 12288 rows affected (3.15 sec)
Records: 12288 Duplicates: 0 Warnings: 0
insert into test select * from test;
Query OK, 24576 rows affected (12.30 sec)
Records: 24576 Duplicates: 0 Warnings: 0
insert into test select * from test;
Query OK, 49152 rows affected (22.52 sec)
Records: 49152 Duplicates: 0 Warnings: 0
insert into test select * from test;
Query OK, 98304 rows affected (41.78 sec)
Records: 98304 Duplicates: 0 Warnings: 0
insert into test select * from test;
Query OK, 196608 rows affected (37.81 sec)
Records: 196608 Duplicates: 0 Warnings: 0
STEP6:查看物理文件大小,默认的mysql数据目录在/var/lib/mysql数据库与该目录下的文件同名
cd /var/lib/mysql/test
du -sh test.ibd
2.1G test.ibd
STEP7:从数据库中删除所有ID=1的行
delete from test where id = 1;
Query OK, 131072 rows affected (33.21 sec)
STEP8:再进入数据库目录查看物理文件大小
du -sh test.ibd
2.1G test.ibd
STEP9:进入数据库使用optimize table命令对表进行碎片整理
optimize table test;
+-----------+----------+----------+-------------------------------------------------------------------+
| Table | Op | Msg_type | Msg_text |
+-----------+----------+----------+-------------------------------------------------------------------+
| test.test | optimize | note | Table does not support optimize, doing recreate + analyze instead |
| test.test | optimize | status | OK |
+-----------+----------+----------+-------------------------------------------------------------------+
STEP10:退出再次查看物理文件大小
du -sh test.ibd
1.6G test.ibd
可以从物理文件大小看出,表中的“空洞”已经被清空,这一特性与数据类型无关,是表本身呈现的问题