当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   是表的数据的文件

一个大的表 拆分 成多个小的表 可以极大的降低 对操作系统的影响,减少资源浪费