当mysql中医个表的总记录数超过了1000W,会出现性能大幅度下降的情况,单性能下降的比率由系统的架构、应用程序、数据库索引、服务器硬件等多种因素而定。数据库多达上亿的数据量,分表之后的单个表 也已经超过了千万,那么单个表的更新等均影响着系统的运行效率。甚至是以条简单的sql都有可能压垮整个数据库,如整个表对某个字段的排序操作等。
我们针对海量数据的优化主要有两种方法:达标拆小表的方式,sql语句的优化
sql语句的优化:可以通过增加索引等来调整,但是数据量的增大会导致索引的维护带价增大。
大表拆小表,一般分有 垂直分割 和 水平分割 两种,一般我们对大的数据表进行分割的情况下使用的是水平分割,为了防止冗余,而且要求字段比较少,所以采用水平分割。
从mysql5.1以后的版本里面增加了一个技术,是以插件的方式加入到mysql中。就是分区技术
分区技术可以解决,硬件上比较大的表带来的影响,逻辑上表名不变。
目前分区技术 有4种分区类型:
RANGE分区:基于属于一个给定连续区间的列值,把多行分配给分区
LIST分区:类似于RANGE分区,区别在于LIST分区是基于列值匹配一个离散值集合中的某个值来进行选择
HASH分区:基于用户定义的表达式的返回值来进行选择的分区,该表达式使用将要插入的表中的这些行的 列值进行计算,这个函数可以包含mysql中有效的、生产非负整数值的任何表达式
KEY分区:类似于按HASH分区,区别在于KEY分区只支持计算一列或多列,且mysql服务器提供其自身的哈希函数。
例子:假定了一个如下的表,该表保存了有20家店的志愿记录,这20加店的标号从1-20.如果你想将其分成4个小分区,那么可以采用RANGE分区,创建的数据库表如下:
mysql>create table employees(
-> id INT NOT NULL, //这是一个ID,××× 不能为空
-> fname VARCHAR(30), // 这是 第一个名字 varchar类型
-> lname VARCHAR(30),
-> hired DATE NOT NULL DEFAULT '1970-01-01', //这是入职时间 时间类型 不能为空
-> separated DATE NOT NULL DEFAULT '9999-12-12', //这是离职时间 和入职一样
-> job_code INT NOT NULL, //这是 员工的编号 ×××,不能为空
-> store_id INT NOT NULL //这是店的编号,×××,不能为空
-> )
-> PARTITION BY RANGE(store_id)( //这里是用RANGE分区的店的编号进行分区
-> PARTITION p0 VALUES LESS THAN(6), //6号店之前的分到 p0 分区里面
-> PARTITION p1 VALUES LESS THAN(11), //下面就不用解释了 就是分到不同的区
-> PARTITION p2 VALUES LESS THAN(16),
-> PARTITION p3 VALUES LESS THAN(21)
-> );
上面的例子 是按照店编号来进行分区,还有我们的用户 或者员工非常多,有上万,那么我们也可以按照他们不同的入职时间来进行分区,也就是按照时间来分区,例子如下:
mysql>create table employees(
-> id INT NOT NULL, //这是一个ID,××× 不能为空
-> fname VARCHAR(30), // 这是 第一个名字 varchar类型
-> lname VARCHAR(30),
-> hired DATE NOT NULL DEFAULT '1970-01-01', //这是入职时间 时间类型 不能为空
-> separated DATE NOT NULL DEFAULT '9999-12-12', //这是离职时间 和入职一样
-> job_code INT NOT NULL, //这是 员工的编号 ×××,不能为空
-> store_id INT NOT NULL //这是店的编号,×××,不能为空
-> )
-> PARTITION BY RANGE(YEAR(hired))( //这里是用year函数来计算出入职的年
-> PARTITION p0 VALUES LESS THAN(1991), //1991年之前的分到 p0 分区里面
-> PARTITION p1 VALUES LESS THAN(2001), //下面就不用解释了 就是分到不同的区
-> PARTITION p2 VALUES LESS THAN(2011),
-> PARTITION p3 VALUES LESS THAN MAXVALUE //如以上无法匹配 剩余的存放一个表里
-> );
下面这张图是刚刚分区所形成的表的文件:
来解释一下:
分区后 总共生成了10个文件,这10个文件分别是:
employees.frm 是表的结构
employees.par 是分区表
employees#P#p0.MYD 是表的索引的文件
employees#P#p0.MYI 是表的数据的文件
一个大的表 拆分 成多个小的表 可以极大的降低 对操作系统的影响,减少资源浪费
转载于:https://blog.51cto.com/yanzhe/1188848