Chinaunix首页 | 论坛 | 博客
  • 博客访问: 663377
  • 博文数量: 66
  • 博客积分: 15
  • 博客等级: 民兵
  • 技术积分: 2204
  • 用 户 组: 普通用户
  • 注册时间: 2010-10-26 21:43
个人简介

曾就职于阿里巴巴担任Oracle DBA,MySQL DBA,目前在新美大担任SRE。[是普罗米修斯还是一块石头,你自己选择!] 欢迎关注微信公众号 “自己的设计师”,不定期有原创运维文章推送。

文章分类

全部博文(66)

文章存档

2017年(2)

2016年(3)

2015年(7)

2014年(12)

2013年(42)

分类: Mysql/postgreSQL

2013-12-11 21:34:22

Hiperformance Mysql 3rd Edition
  MySQL提供了大量不同的数据类型,选择合适的数据类型y有时是决定性能好坏的关键。如下是一些关于更好选择数据类型的建议:
  1.越小的数据类型通常越好
    一般来讲,尝试用最小的数据类型,可以正确的帮助你存储和代表你的数据。更小的数据类型,通常也会更快,因为它使用了更小的磁盘空间,CPU Cache。同时可以减少CPU的执行周期。
  2.越简单越好。
    简单的数据类型需要的CPU执行周期通常也会更少。比如,整数的比较开销比字符串的开销更少,因为字符串有字符集和相应的校对规则,导致字符串的比较也更加复杂。在很多数据库中通常用整数来储存IP地址,用MYSQL内建的日期类型来存储时间而不是用字符串。
  3.如果可以不适用NULL,尽量不要使用NUll
    在列的字段属性上,如果该字段本身不可能为NULL,尽量字段属性 NOT NULL,除非你打算在该字段上存储NULL值.
    MYSQL在优化查询期间如果引用到可以为空的字段,优化会比较困难。因为可以为空的字段,导致索引的建立,索引统计信息的收集和字段值得比较都比较复杂。同时,一个可以为空的字段也会使用更多的存储空间,同时需要mysql内部执行特殊的处理。在innodb内部,每个可以为NULL的值,需要一个bit来表示,对于空间十分匮乏的数据库来说,能省则省。


如下分析一张目前OLTP的表:
mysql> show create table account\G;
*************************** 1. row ***************************
       Table: account
Create Table: CREATE TABLE `account` (
  `id` int(11) unsigned NOT NULL,
  `account` char(32) NOT NULL,
  `password` char(32) NOT NULL,
  `gm` int(11) default '1000',
  `thread` tinyint(4) NOT NULL default '0',
  `time` int(11) NOT NULL default '0',
  `last_logout` int(11) NOT NULL default '0',
  `online_time` int(11) NOT NULL default '0',
  `offline_time` int(11) NOT NULL default '0',
  `ip` varchar(16) NOT NULL default '',
  `lastplayerid` bigint(20) NOT NULL default '0',
  `authed` int(11) unsigned NOT NULL default '1',
  `idcardno` varchar(32) NOT NULL default '',
  `goldpoint` bigint(20) NOT NULL default '0',
  `bankcard` int(4) NOT NULL default '0',
  `protectword` char(36) NOT NULL default '',
  `end_protectedtime` int(11) unsigned NOT NULL default '0',
  `err_num` int(11) unsigned NOT NULL default '0',
  `err_time` int(11) unsigned NOT NULL default '0',
  `hack_check_errcount` int(11) NOT NULL default '0',
  `plugdata` blob,
  `ppcardinfo` blob,
  `pp_card_info` varchar(2048) default NULL,
  `last_login_area` int(11) NOT NULL default '0',
  `second_password` blob,
  `login_check_details` blob,
  `base` blob,
  `msg_authed` int(4) NOT NULL default '1',
  `safe_email_status` int(11) NOT NULL default '-1',
  `safe_mobile_status` int(11) NOT NULL default '-1',
  `vip_level` tinyint(4) default '0',
  `vip_points` int(11) NOT NULL default '0',
  `last_award_level` tinyint(4) default '0',
  `last_award_time` int(11) default '0',
  `vip_quest` tinyint(4) default '0',
  `vip_time` int(11) NOT NULL default '0',
  `qiangzhu` int(11) NOT NULL default '0',
  `liquan` bigint(20) NOT NULL default '0',
  PRIMARY KEY  (`account`),
  UNIQUE KEY `index_id` (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
对于这个表,其实可以看到很多明显的问题,最明显的就是primary key 使用字符串account字段,导致插入数据按照account排序,而不是用自增主键,会导致大量block分裂,导致碎片过多,影响dml效率。同时我们看到很多时候使用int(n)来限制一个整形的长度。其实对于int(n)的含义我想用 high performance mysql中的一段话来解释:
MySQL lets you specify a “width” for integer types, such as INT(11). This is meaningless
for most applications: it does not restrict the legal range of values, but simply specifies
the number of characters MySQL’s interactive tools (such as the command-line client)
will reserve for display purposes. For storage and computational purposes, INT(1) is
identical to INT(20).
其实对于int(n)其实对大多数应用来讲,根本没有多大意义。而且它也不能限制int的合法范围(-2147483648~2147483647),只是为了让MYSQL的交互工具显示的时候只显示N个字符而已。而且很多字段也可以加上NOT NULL属性,来提高性能。
同时保证每个字段都使用它最小的空间来存储。


尽量在设计表的前期就规划好字段的范围,并选择合适的类型,可能只是一点点小小的更改,有时候对整个系统来讲可能带来性能极大的提升。数据量存储空间越小,越能提升数据库的性能。


阅读(2689) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~