首页 文章详情

Mysql_数据类型优化_2

雲海垂钓 | 114 2021-11-26 23:58 0 0 0
UniSMS (合一短信)

关于BLOB、TEXT类型:

    BLOB与TEXT是为了存储很大的数据而设计的字符串数据类型,分别采用二进制和字符方式存储,实际上它们分别属于两组不同的数据类型家族:

字符类型:TINYTEXT, SMALLTEXT, TEXT, MEDIUMTEXT, LONGTEXT

二进制类型:TINYBLOB, SMALLBLOB, BLOB, MEDIUMBLOB, LONGBLOB。


    至于BLOB与TEXT的不同,BLOB类型存储的是二进制数据,没有排序规则或字符集。与其他的类型不同,Mysql会将每个BLOB,TEXT值当做一个独立的对象处理,存储引擎在存储时通常进行特殊的处理,当它们的值太大是,InnoDB会使用专门的外部存储区域来进行存储,此时每个值在行内需要1~4个字节存储一个指针,然后在外部存储区域存储实际的值。


    Mysql对BLOB和TEXT进行排序与其他类型不同,它只对每个列的最前max_sort_length字节排序,而不是整个字符串,或者使用order by sustring(column,length),这样可以减少max_sort_length的配置,减少因为对整个字符串做排序带来无用的资源浪费。此外,Mysql不能对BLOB和TEXT列全部长度的字符串进行缩引,也不能使用这些索引消除排序。

    

磁盘临时表和文件排序

    因Memory引擎不支持BLOB、TEXT,所以查询使用了BLOB,TEXT的列,且需要使用临时隐式表,将不得不使用MyIASM磁盘临时表,即使只有几行数据。这会性能开销很严重,即使配置Mysql将临时表存储在内存块RAM上,仍然需要许多昂贵系统调用。


    对于此问题,最好的方式是尽量避免使用BLOB和TEXT类型,若无法避免,可以尝试在所有用到BLOB字段的地方都用substring(column, length)将列值转为字符串(在order by子句中同样适用),这样就可以使用内存临时表,但是需要确保截取的字符串足够短,不会使临时表的大小超过max_heap_table_size或tmp_tbale_size,超过后Mysql会将内存临时表转换为MyISAM磁盘临时表,最坏情况下的长度分配对于排序操作也是一样的处理。

    对于上述的概念,有一个例子可以较为形象的理解一下:假设有一个1000w行的表,占用了几个GB的磁盘空间,其中有一个utf8的字符集varchar(1000)列,每个字符最多使用3个字节,在最坏情况下就需要3000自己的空间,在使用order by中用到这个列,并且查询扫描整个表,那么为了排序就要需要超过30GB的临时表。


good-icon 0
favorite-icon 0
收藏
回复数量: 0
    暂无评论~~
    Ctrl+Enter