设为首页 收藏本站
查看: 1978|回复: 0

[经验分享] mysql tinyint和char(1)性能对比

[复制链接]

尚未签到

发表于 2018-10-11 06:57:03 | 显示全部楼层 |阅读模式
  在数据库设计的时候会遇到很多只需要0、1、2这种固定几个值的状态字段,基本上都建议设置为只占一字节的tinyint类型,有些觉得char(1)是一样,毕竟char(1)存储数字和字母时一个字符也只是占一个字节
  mysql是用c++写的,而在c++中字符类型是存放对应ascii码的二进制到存储空间,而整型数字是直接存数字的二进制,虽然最终都是二进制存储,但是环节上有少许不同,同样在msyql查找时也会有所不同,下图摘自小白版c++教程《c++ primer plus》:
DSC0000.jpg

  今天对tinyint和char(1)做了个简单测试,分表建两个表t1、t2,结构如下:
  mysql> show create table t1\G
  *************************** 1. row ***************************
  Table: t1
  Create Table: CREATE TABLE `t1` (
  `_id` int(11) NOT NULL AUTO_INCREMENT,
  `id` tinyint(4) DEFAULT NULL,
  `title` text,
  PRIMARY KEY (`_id`),
  KEY `id` (`id`)
  ) ENGINE=InnoDB AUTO_INCREMENT=2400096 DEFAULT CHARSET=utf8
  1 row in set (0.00 sec)
  mysql> show create table t2\G
  *************************** 1. row ***************************
  Table: t2
  Create Table: CREATE TABLE `t2` (
  `_id` int(11) NOT NULL AUTO_INCREMENT,
  `id` char(1) DEFAULT NULL,
  `title` text,
  PRIMARY KEY (`_id`),
  KEY `id` (`id`)
  ) ENGINE=InnoDB AUTO_INCREMENT=2400096 DEFAULT CHARSET=utf8
  1 row in set (0.00 sec)
  两个表唯一不同为id字段类型,总数据量都为2400096,id只有0、1、2三个,为了两个表的数据一样且磁盘上分布也一样,降低IO对测试的影响,分别加载的数据如下:

  mysql> select>  +------+----------+

  |>  +------+----------+
  |    0 |  1199998 |
  |    1 |  1199998 |
  |    2 |       99 |
  +------+----------+
  3 rows in set (0.55 sec)

  mysql> select>  +------+----------+

  |>  +------+----------+
  | 0    |  1199998 |
  | 1    |  1199998 |
  | 2    |       99 |
  +------+----------+
  3 rows in set (0.77 sec)
  查看执行计划:

  mysql> explain select _id from test.t2 where>  +----+-------------+-------+------+---------------+------+---------+-------+---------+--------------------------+

  |>  +----+-------------+-------+------+---------------+------+---------+-------+---------+--------------------------+

  |  1 | SIMPLE      | t2    | ref  |>  +----+-------------+-------+------+---------------+------+---------+-------+---------+--------------------------+
  1 row in set (0.00 sec)

  mysql> explain select _id from test.t1 where>  +----+-------------+-------+------+---------------+------+---------+-------+---------+-------------+

  |>  +----+-------------+-------+------+---------------+------+---------+-------+---------+-------------+

  |  1 | SIMPLE      | t1    | ref  |>  +----+-------------+-------+------+---------------+------+---------+-------+---------+-------------+
  1 row in set (0.00 sec)
  两个表都使用了id索引,再看看information_schema.tables的信息是否和之前理解的存储字节大小是否有出入:
  mysql> select DATA_LENGTH/1024/1024,INDEX_LENGTH/1024/1024,data_free from tables where table_name in ('t1','t2');
  +-----------------------+------------------------+-----------+
  | DATA_LENGTH/1024/1024 | INDEX_LENGTH/1024/1024 | data_free |
  +-----------------------+------------------------+-----------+
  |          310.81250000 |            27.56250000 |         0 |
  |          313.81250000 |            29.56250000 |         0 |
  +-----------------------+------------------------+-----------+
  2 rows in set (0.00 sec)
  两个表大小相差不多,确认char(1)和tinyint占字节数相同,现在直接看执行时间:
  mysql> show profiles;
  +----------+------------+---------------------------------------------------------------+
  | Query_ID | Duration   | Query                                                         |
  +----------+------------+---------------------------------------------------------------+

  |        1 | 0.60804275 | select count(*) from (select _id from test.t1 where>
  |        2 | 0.59277575 | select count(*) from (select _id from test.t1 where>
  |        3 | 0.60398000 | select count(*) from (select _id from test.t1 where>
  |        4 | 0.69068025 | select count(*) from (select _id from test.t2 where>
  |        5 | 0.69654200 | select count(*) from (select _id from test.t2 where>
  |        6 | 0.67788800 | select count(*) from (select _id from test.t2 where>  +----------+------------+---------------------------------------------------------------+
  这样就很明显可以看出为char(1)字段的t2表查询时消耗时间偏多,如果几条几百条的情况根本看不出char(1)和tinyint的差别,毕竟现在CPU的效率是非常高的,这里测试的利用了id=1的数据,有1199998条,这样就可以看出点差别了!!虽然效率差别不是很大,为了生产环境统一以及提升QPS还是使用短小的整型更好


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-620097-1-1.html 上篇帖子: Mysql数据库集群简单配置 下篇帖子: Mysql之运用MHA的功能实现服务高可用
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表