高性能Mysql--Schema与数据类型优化

目录

选择优化的数据类型

选择数据类型的原则

数据类型

整数

实数

字符串

日期和时间

选择标识符

schema设计中的陷阱

范式和反范式

缓存表和汇总表

物化视图

计算器表

加快ALTER TABLE 操作的速度

只修改.frm文件

CHANGE, MODIFY, 和ALTER 区别


良好的逻辑设计和物理设计是高性能的基石,应该根据系统将要执行的查询来设计schema。

选择优化的数据类型

选择数据类型的原则

  • 更小的通常更好

尽量使用可以**正确存储**的**最小**数据类型。

  • 简单就好

简单数据类型需要更少CPU周期。

  • 尽量避免NULL

可为NULL的列使索引,存储等更复杂。

数据类型

分类 类型 存储大小(字节) 范围 范围(无符号)
整数 tintyint 1 (-128,127) (0,255)
smallint 2 (-32 768,32 767) (0,65 535)
mediumint 3 (-8 388 608,8 388 607) (0,16 777 215)
int 4 (-2 147 483 648,2 147 483 647) (0,4 294 967 295)
bigint 8 ... ...
实数 float 4 ... ...
double 8 ... ...
decimal(m,n) 不定 ... ...
日期和时间 date 3 1000-01-01/9999-12-31  
time 3 838:59:59'/'838:59:59'  
year 1 1901-2155  
datetime 8 1000-01-01 00:00:00/9999-12-31 23:59:59  
timestamp 4 1970-01-01 -- 2037  
字符串 char(m) m 0-255字节  
varchar(m) / 0-65535 字节  
tinyblob,tinytext   0-255字节  
blob,text   0-65 535字节  
mediumblob   2^24 - 1 字节  
mediumtext
longblob,longtext   2^32 -1 字节  
bit n  

不同引擎不同。

innodb,[n/8]

  binary(n) n   n个字节
  varbinary(n)      

整数

整数类型有可选的UNSIGNED 属性,表示不允许负值。

整数类型的选择只决定了MYSQL怎么在内存和磁盘中保存数据,整数计算一般使用64位的bigint,即使32位环境也如此(一些聚合函数例外,使用decimal或double)。

实数

decimal支持精确计算,float和double 由于CPU支持,比decimal更快。decimal在MYSQL 5.0以上被保存在一个二进制中(每4个字节存9个数字)。decimal(18,9)使用9个字节,小数点一个字节,整数部分4个字节,小数部分4个字节。

浮点类型存储同样范围的值时,比decimal节省空间,MYSQL使用double作为浮点计算的类型。

字符串

存储引擎存储char或者varchar值的方式,在内存中和磁盘上可能是不一样

VARCHAR,可变长,需要1或2个字节存储长度信息。

char存储时,会把末尾空格截断,内部存储时,添加空格,读取出来时,默认空格会发现不存在了

binary填充时默认填充的是\0,而不是空格。

日期和时间

MYSQL能存储的最小时间粒度为秒。但是MYSQL也可以使用微秒级的粒度进行临时运算。

如果需要微秒计算,则可以用bigint存储时间戳,或者double存储秒之后的小数部分。

除了特殊要求,通常尽量使用timestamp,它比datetime空间效率更高。

选择标识符

为标识列选择合适的数据类型非常重要。不仅考虑存储,还要考虑怎么执行计算和比较。

一旦选择了类型,要确保所有的关联表中关联字段都使用相同类型。

整数类型是个合适的选择。

如果可能避免使用字符串类型作为标识列。

如果是UUID,应该移除‘-’,更好的做法是UNHEX转成16字节数字,存储在binary(16)中。

ORM等产生的SQL会导致很严重的性能问题。

schema设计中的陷阱

  • 太多的列
  • 太多关联
  • 全能枚举
  • 变相枚举
  • 确实需要NULL,用其他不可用到的值代替,增加复杂度

范式和反范式

根据经验吧

缓存表和汇总表

数据冗余表,提高查询

物化视图

物化视图指事先计算存储在磁盘上的表,MYSQL并不原生支持,可以使用Flexviews。

计算器表

增加更多的slot,以减少并发的机会。

加快ALTER TABLE 操作的速度

Mysql的alter table操作的性能对大表示个问题,Mysql执行大部分修改表的结构操作的方法是用新的结构创建一个空表,从旧表查出数据插入到新表,然后删除旧表。

mysql5.1之后,支持“在线”操作,这些功能不需要在整个操作过程中锁表。最近innodb也支持通过排序来创建索引,这使得索引更快且有个紧凑的索引布局。

不是所有的alter table操作都会引起重建表结构。有2种方法可以改变或者删除一个列的默认值

ALTER TABLE MODIFY COLUMN 将导致表重建。

ALTER TABLE ALTER COLUMN  会直接修改.frm文件不涉及表数据,所以很快。

只修改.frm文件

不受官方支持

CHANGEMODIFY, 和ALTER 区别

ALTER [COLUMN] col_name {SET DEFAULT literal | DROP DEFAULT}
CHANGE [COLUMN] old_col_name new_col_name column_definition
MODIFY [COLUMN] col_name column_definition   [FIRST | AFTER col_name]
  • CHANGE:

    • 可重命名列和修改列的定义

    • Has more capability than MODIFY, but at the expense of convenience for some operations. CHANGE requires naming the column twice if not renaming it.

    • With FIRST or AFTER, can reorder columns.

  • MODIFY:

    • Can change a column definition but not its name.

    • More convenient than CHANGE to change a column definition without renaming it.

    • With FIRST or AFTER, can reorder columns.

  • ALTER: Used only to change a column default value.

更多关于alter table 性能问题参考: https://www.cnblogs.com/hllnj2008/p/5045752.html

猜你喜欢

转载自blog.csdn.net/demon7552003/article/details/106583026