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

[经验分享] MySQL优化四(优化表结构)

[复制链接]

尚未签到

发表于 2017-12-12 08:00:44 | 显示全部楼层 |阅读模式
MySQL优化四(优化表结构)MySQL优化四(优化表)

  昨晚吃吃喝喝的太多,熬夜到凌晨二点。今天头发杂乱,脸庞憔悴,像是吸毒了。下午去买衣服,肚子一看大了不少。奈何女朋友还没有一个,就已经发福了。管不住口,迈不开腿。


一、优化表结构
  1.尽量将表字段定义为NOT NULL约束,这时由于在MySQL中含有空值的列很难进行查询优化,NULL值会使索引以及索引的统计信息变得很复杂,可以使用0或者空字符串来代替。
  2.可以使用enum、set 等符合数据类型。对于只包含特定类型的字段。不过在工作过程中一般就使用tinyint 来表示了。
  3.数值型字段的比较比字符串的比较效率高得多,字段类型尽量使用最小、最简单的数据类型。IP地址可以使用int类型。

二、表拆分

1、垂直拆分
  垂直拆分按照字段进行拆分,其实就是把组成一行的多个列分开放到不同的表中,这些表具有不同的结构,拆分后的表具有更少的列,例如用户表中的一些字段可能经常访问,可以把这些字段放进一张表里。另外一些不经常使用的信息就可以放进另外一张表里。插入的时候使用事务,也可以保证两表的数据一致。缺点也很明显,由于拆分出来的两张表存在1:1的关系,需要使用冗余字段,而且需要join操作,我们在使用的时候可以分别取两次,这样的来说既可以避免join操作,又可以提高效率。

2、水平拆分
  水平拆分按照行进行拆分,常见的就是分库分表。以用户表为例,可以取用户ID,然后使用php的十进制转换16进制的方法 dechex,截取其中的第一个字符,将用户均匀的分配进这 0-9 、a-f 这16个表中。查找的时候也按照这种规则,又快又方便。当然类似的规则很多,也可以使用求余法,按照余数将数据分发进不同的表中。有些表业务关联比较强,那么可以使用按时间划分的。以我公司的某业务为例,每天都要新建一张表。这种业务类型就是需要高速插入,但是对于查询的效率不太关心。表越大,插入数据所需要索引维护的时间也就越长。

三、分区
  分区这个概念,我第一次在实践中看到是在去年,数据中心的表按照时间一个月分成一个区。我从这些表中读取数据,然后继续做后续的业务处理。一般来说在主业务中很少使用这种分区概念,使用分区是大数据处理后的产物。比如系统用户的注册推广等等,会产生海量的日志,当然也可以按照时间去建立多张表,但在实际操作中,就发生过一次运维人员忘记切换表,导致数据报错的紧急事件。可见分区适用于日志记录,查询少,一般用于后台的数据报表分析。对于这些数据汇总需求,需要很多日志表去做数据聚合,我们能够容忍1s到2s的延迟,只要数据准确能够满足需求就可以。
  MySQL主要支持4种模式的分区:range分区、list预定义列表分区,hash 分区,key键值分区。后几种没有看到数据中心的同事用过,可能是操作不方便,应用不广泛,所以就暂且不讲了。
-- 创建表  
create table testpar
  
(
  
f_userid int unsigned not null default 0,
  
f_date datetime
  
)engine=innodb,
  

  
-- 分区
  
alter table testpar  partition by range columns(f_date) (
  
partition p0 values less than ('2017-01-31'),
  
partition p2 values less than ('2017-02-20')
  
);
  

  
-- 查看表结构
  
mysql> show create table testpar\G
  
*************************** 1. row ***************************
  
Table: testpar
  
Create Table: CREATE TABLE `testpar` (
  
`f_userid` int(10) unsigned NOT NULL DEFAULT '0',
  
`f_date` datetime DEFAULT NULL
  
) ENGINE=InnoDB DEFAULT CHARSET=utf8
  
/*!50500 PARTITION BY RANGE  COLUMNS(f_date)
  
(PARTITION p0 VALUES LESS THAN ('2017-01-31') ENGINE = InnoDB,
  
PARTITION p2 VALUES LESS THAN ('2017-02-20') ENGINE = InnoDB) */
  
1 row in set (0.00 sec)

运维网声明 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.iyunv.com/thread-423215-1-1.html 上篇帖子: 搭建连接MySql的三层架构的ASP.NetCore2.0的WebApi 下篇帖子: binlog2sql之MySQL数据闪回实践
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

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

扫描微信二维码查看详情

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


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


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


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



合作伙伴: 青云cloud

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