日期:2014-05-16  浏览次数:20699 次

高性能MySql进化论(二):数据类型的优化_下

·        BLOB/TEXT
在实际的应用程序中往往需要存储两种体积较大的数据,一种是较大的Binary数据,e.g. 一张10M的图片,另外一种是 较大的文本 e.g.一篇几万字的文章。在Oracle中有BOLB和CLOB来应对这两种数据,而在MySQL中对应的是BLOB以及TEXT.
鉴于这两种数据类型的特殊性,在MySQL中对BLOB以及TEXT的存储和操作做了特殊的处理:
          1) BLOB/TEXT 的值往往是作为对象来处理,这些对象有自己的ID,以及独立的存储空间
          2) BLOB/TEXT的值被用来排序的时候,只有前N个字节会被使用,N 对应的是数据库中的一个常量值 (max_sort_length), 如果你想指定更多的字节被用来排序,那么你可以增加max_sort_length的值或者是使用ORDER BY SUBSTRING(column, length)函数来处理
          3) 当BLOB/TEXT 被用作索引或者排序的时候,不能使用整个字段的值.
在万不得已的情况下要避免把BOLB/TEXT用作索引或是排序

因为MySQL 的Memory 引擎不支持BLOB 和TEXT 类型,所以,如果查询的过程中涉及到BLOB /TEXT,则需要使用MyISAM 磁盘临时表,即使只有几行数据也是如此(在最新的Percona Server 的Memory 引擎支持BLOB 和TEXT 类型)。

Memory引擎频繁的访问磁盘临时表会产生严重的性能开销,最好的解决方案是尽量避免使用BLOB 和TEXT 类型。如果实在无法避免,有一个技巧是在所有用到BLOB 字段的地方都使用SUBSTRING(column, length) 将列值转换为字符串(在ORDER BY 子句中也适用),这样就可以使用内存临时表了。但是要确保截取的子字符串足够短,不会使临时表的大小超过max_heap_table_size 或tmp_table_size,超过以后MySQL 会将内存临时表转换为MyISAM 磁盘临时表。

 

最坏情况下的长度分配对于排序的时候也是一样的,所以这一招对于内存中创建大临时表和文件排序,以及在磁盘上创建大临时表和文件排序这两种情况都很有帮助。例如,假设有一个1 000 万行的表,占用几个GB 的磁盘空间。其中有一个utf8字符集的VARCHAR(1000) 列。每个字符最多使用3 个字节,最坏情况下需要3 000字节的空间。如果在ORDER BY 中用到这个列,并且查询扫描整个表,为了排序就需要超过30GB 的临时表


·       DATETIME/TIMESTAMP
在MySQL中包含两种时间格式 DATETIME,TIMESTAMP, 通常在使用的过程中这两种类型区别不是很大,但是在细节上还是存在差别

 

DATETIME

TIMESTAMP

占用空间

8Bytes

4Bytes

可表示区间(年)

1001-9999

1970-2038

是否与时区有关

存储内容

日期和时间封装到格式为YYYYMMDDHHMMSS 的整数中

保存了从1970 年1 月1 日午夜(格林尼治标准时间)以来的秒数,它和UNIX 时间戳相同

显示方式是否与时区有关

否(ANSI 标准定义的日期和时间表示方法)

特殊属性

 

(1)TIMESTAMP 列默认为NOT NULL,默认值为当前时间

因为TMESSTAMP会