MySQL大数据优化以及分解(下篇)

http://xiaorenwutest.blog.51cto.com


MySQL大数据优化以及分解(下篇)


前言:在上一章的内容当中说过公司中的数据过大或者访问量过多都会导致数据库的性能降低,过多的损耗磁盘i/o和其他服务器的性能,严重会导致宕机。根据这种情况我们给出了解决方法,那么接下来我们继续:

上次说到了分表和分区:首先让我们回顾下分表和分区的区别:

分表:

将一个大表分解成若干个小表,每个小表都有独立的文件.MYD/.MYI/.frm三个文件

分区:

将存放数据的数据块变多了,表还是一张大表,在后面会有一个总结。

讲到分区了上次,这次主要还是分区的内容;分区主要包括五个分区类型:

1):range分区:

把连续区间的列值分配给分区,而且这些区间不能相互重叠,

那么我们就举个例子来验证下,range分区和未分区的不同之处:{性能比拼}

首先创建一个未分区的库和表

MySQL>create database test;

mysql> create table test.tab1(c1 int,c2 varchar(30),c3 date);

接下来创建一个分区的表,按照年份进行拆分

mysql> use test

mysql> CREATE TABLE tab2 ( c1 int, c2 varchar(30) , c3 date )

PARTITION BY RANGE (year(c3)) (PARTITION p0 VALUES LESS THAN (1995),

PARTITION p1 VALUES LESS THAN (1996) , PARTITION p2 VALUES LESS THAN (1997) ,

PARTITION p3 VALUES LESS THAN (1998) , PARTITION p4 VALUES LESS THAN (1999) ,

PARTITION p5 VALUES LESS THAN (2000) , PARTITION p6 VALUES LESS THAN (2001) ,

PARTITION p7 VALUES LESS THAN (2002) , PARTITION p8 VALUES LESS THAN (2003) ,

PARTITION p9 VALUES LESS THAN (2004) , PARTITION p10 VALUES LESS THAN (2010),

PARTITION p11 VALUES LESS THAN MAXVALUE );

最后一行表示有可能在插入年份数据比2005大的数据可以插入,如果没有将会出错

刚才创建的两个表tab1和tab2没有数据只有一个空表;接下来为它们插入数据;

多一点,不然看不出效果;1000000条数据

创建存储过程,需要使用界定符

mysql> delimiter &&//指定存储过程结束符

mysql>CREATE PROCEDURE load_part_tab()

begin

declare x int default 0;

while x < 1000000

do

insert into test.tab1

values (x,‘testing partitions‘,adddate(‘1995-01-01‘,(rand(x)*36520) mod 3652));

set x = x + 1;

end while;

end

&&

rand()函数在0和1之间的随机数,如果rand(n)中的n被指定,它将作为一个值,再次不做过多的叙述;大家可以查看相关的资料

将load_part_tab向test.tab1表中插入1000000条数据

查看一下是否插入成功

接下来向tab2表中也插入1000000条的数据

mysql> insert into test.tab2 select * from test.tab1;

注:这条sql语句属于嵌套式,将后面执行的结果交给前面的执行

查看一下是否成功;

接下来让我们拭目以待;测试sql性能:

tab1表的查询:

mysql> select count(*) from test.tab1 where c3 > ‘1995-01-01‘ and c3 < ‘1995-12-31‘;

tab2表的查询:

mysql>select count(*) from test.tab2 where c3 > ‘1995-01-01‘ and c3 < ‘1995-12-31‘;

通过explain语句来分析下它们的执行情况:

果表明分区的效果要比为分区的效果好太多了。既然这样我们就现在这个前题之下为tab1

表和tab2表创建索引,看看它们的效果如何:

刷新下表的缓存,进行查询:

tab1表查询如下

tab2表的查询如下;

由此结果可见索引创建之后还是分区后的速度快,但是结果相差不大,但是如果数据结构复杂,数据量庞大的情况之下,结果会越发的显著

不知道大家看明白了没有,如果没有我们在举个例子,主要因为range分区在工作中使用较多,所以再次在举个例子:

mysql>create database test2

mysql> CREATE TABLE employees (    ==========>创建一个employees表

id INT NOT NULL,                 ========> ID号为整形不能为空

fname VARCHAR(30),              ===========>姓氏

lname VARCHAR(30),              ===========>名字

hired DATE NOT NULL DEFAULT ‘1970-01-01‘,     ==========> 雇佣的日期,不能为空

separated DATE NOT NULL DEFAULT ‘9999-12-31‘,  ==========>离开的日期,不能为空

job_code INT NOT NULL,      =============>   员工职务的工号,不能为空

store_id INT NOT NULL       ===========> 商店ID号,不能为空

)

partition BY RANGE (store_id) (     ============> 分区范围以商店ID为准

partition p0 VALUES LESS THAN (6), =========> p0包括小于6的id号

partition p1 VALUES LESS THAN (11), ===========>p1包括小于11ID号

partition p2 VALUES LESS THAN (16), ============>p2包括小于16ID号

partition p3 VALUES LESS THAN (21) ===============>p3包括小于21的ID号

);

上面的分区方式说明了商店1-5号;工作的员工都被保存在了p0区域当中,6-11的商店员工被保存在了p1区域中,其他的一次类推;
但是需要注意的是,如果从其他地方区域调来了一个员工如(81,‘lll’,‘xxff’,‘1998-06-25’,‘2001-26-25’,25,13)是否可以加入呢? 当然可以而且还是p2区域,这要查看他的商店id号为13,所以可以。那么我们来验证一下OK

插入成功

那如果又有一个商店ID号为25的员工是否能加入呢?

插入失败,由于没有规则把store_id大于20的商店包含在内,服务器将不知道把该行保存在何处,将会导致错误。要避免这种错误,可以创建maxvalue分区,所有不在指定范围内的记录都会被存储到maxvalue所在的分区中。

我们可以通过sql语句修改次分区:

mysql> alter table employees add partition (partition p4 values less than maxvalue);

可以看出修改之后的分区来自商店ID为25的员工可以加入。

介绍了range分区,那么我们进行个总结对range:

基于属于一个给定连续区间的列值,把多行分配给分区。这些区间要连续且不能相互重叠

而且在最后的区域中设置maxvalue防止大于区域的内容无法插入。

2)list分区;

比较类似range分区,区别在于range的值是连续的,而list是散值集合在一个行中,或许大家听的不太明白,一会给大家举个例子看下。

 LIST分区通过使用“PARTITION BY LIST(expr)”来实现,其中“expr” 是某列值或一个基于某个列值、并返回一个整数值的表达式,然后通过“VALUES IN (value_list)”的方式来定义每个分区,其中“value_list”是一个通过逗号分隔的整数列表。

我们还以商店这个例子为大家进行演示,正好和range进行对比:

首先创建库

mysql> create database tty;

 

这样在表中增加或者删除制定区域的员工记录变得容易起来,假如说pNorth商店倒闭了现在需要将员工记录全部删掉可以使用“ALTER TABLE employees DROP PARTITION pWest;”来进行删除,它与具有同样作用的DELETE (删除)查询“DELETE query DELETE FROM employees WHERE store_id IN (4,12,13,14,18);”比起来,要有效得多。

接下来为大家介绍下另外的三种分区方式:作为了解

3)HASH分区;

这种模式允许DBA通过对表的一个或多个列的Hash Key进行计算,最后通过这个Hash码不同数值对应的数据区域进行分区。

hash分区的目的是将数据均匀的分布到预先定义的各个分区中,保证各分区的数据量大致一致。分区中; MYSQL自动完成这些工作,用户所要定一个列值或者表达式,以及指定分区的表将要被分割成的分区数量。

接下来举例说明:

mysql> create table t_hash( a int(11), b datetime) partition by hash(year(b)) partitions 4;

接下来插入点数据,让我们来验证下:

那么看一下MySQL自动会将这条数据插入到那个分区呢?

我们还可以通过系统数据库information_schema查看下ll库中的t_hash表的树形结构:

前期应为创建了4个分区所以这里会显示4个

  

这里只有p2表当中有数据,其他的三个都没有数据

 

4)key分区:

key分区和hash分区相似,不同在于hash分区是用户自定义函数进行分区,key分区使用mysql数据库提供的函数进行分区,对于其他存储引擎mysql使用内部的hash函数。

创建的sql语句为:

mysql> create table t_key( a int(11), b datetime) partition by key(b) partitions 4;

 

为其插入一条sql语句:

 

我们看一下

   

上面的RANGE、LIST、HASH、KEY四种分区中,分区的条件必须是整形,如果不是整形需要通过函数将其转换为整形。

5)columns分区

mysql-5.5开始支持COLUMNS分区,可视为RANGE和LIST分区的进化,COLUMNS分区可以直接使用非整形数据进行分区。COLUMNS分区支持以下数据类型:
  所有整形,如INT SMALLINT TINYINT BIGINT。FLOAT和DECIMAL则不支持。
  日期类型,如DATE和DATETIME。其余日期类型不支持。
  字符串类型,如CHAR、VARCHAR、BINARY和VARBINARY。BLOB和TEXT类型不支持。
COLUMNS可以使用多个列进行分区。

最后为大家做一个完整的总结;从不同方面介绍分表和分区的不同之处

mysql分表和分区有什么区别呢

1实现方式上

a) mysql的分表是真正的分表,一张表分成很多表后,每一个小表都是完整的一张表,都对应三个文件,一个.MYD数据文件,.MYI索引文件,.frm表结构文件。

b) 分区不一样,一张大表进行分区后,他还是一张表,不会变成二张表,但是他存放数据的区块变多了

2数据处理上

a)分表后,数据都是存放在分表里,总表只是一个外壳,存取数据发生在一个一个的分表里面。

b)分区呢,不存在分表的概念,分区只不过把存放数据的文件分成了许多小块,分区后的表呢,还是一张表,数据处理还是由自己来完成。

3提高性能上

a)分表后,单表的并发能力提高了,磁盘I/O性能也提高了。并发能力为什么提高了呢,因为查寻一次所花的时间变短了,如果出现高并发的话,总表可以根据不同的查询,将并发压力分到不同的小表里面。

b)mysql提出了分区的概念,主要是想突破磁盘I/O瓶颈,想提高磁盘的读写能力,来增加mysql性能。
在这一点上,分区和分表的测重点不同,分表重点是存取数据时,如何提高mysql并发能力上;而分区呢,如何突破磁盘的读写能力,从而达到提高mysql性能的目的。

4实现的难易度上

a)分表的方法有很多,用merge来分表,是最简单的一种方式。这种方式跟分区难易度差不多,并且对程序代码来说可以做到透明的。如果是用其他分表方式就比分区麻烦了。

b)分区实现是比较简单的,建立分区表,根建平常的表没什么区别,并且对开代码端来说是透明的。

mysql分表和分区有什么联系

1.都能提高mysql的性高,在高并发状态下都有一个良好的表现。

2.分表和分区不矛盾,可以相互配合的,对于那些大访问量,并且表数据比较多的表,我们可以采取分表和分区结合的方式,访问量不大,但是表数据很多的表,我们可以采取分区的方式等。

3.分表技术是比较麻烦的,需要手动去创建子表,app服务端读写时候需要计算子表名。采用merge好一些,但也要创建子表和配置子表间的union关系。
4.表分区相对于分表,操作方便,不需要创建子表。

其实我所写的只不过是mysql的冰山一角,另外有哪里不对的希望大家指点。

下一次为大家带来MySQL的还原和备份

 

时间: 2024-10-13 20:09:40

MySQL大数据优化以及分解(下篇)的相关文章

MySQL 大数据优化

大数据量的系统的数据库结构如何设计: 1.把你表中经常查询的和不常用的分开几个表,也就是横向切分 2.把不同类型的分成几个表,纵向切分 3.常用联接的建索引  4.服务器放几个硬盘,把数据.日志.索引分盘存放,这样可以提高IO吞吐率 5.用优化器,优化你的查询 6.考虑冗余,这样可以减少连接 7.可以考虑建立统计表,就是实时生成总计表,这样可以避免每次查询都统计一次 8.用极量数据测试一下 MySql 优化: 对 mysql 优化是一个综合性的技术,主要包括: 1.表的设计合理性(符合 3NF)

MySQL大数据的优化以及分解存储

            MySQL大数据的优化以及分解存储 前言:在上一章介绍了MySQL的优化以及优化的思路,那么如果有一种情况如果数据库已经建立好了索引,在使用sql语句索引查询时:但是在慢查询日志当中任然找到了之前的sql语句会有哪几种情况: 1):sql语句的索引没有起到效果, 2):查询的数据量过大,造成数据的查询缓慢, 在工作当中每个数据库都会存在庞大的数据量,比如说访问量等等都会造成数据的查询缓慢,那么如何解决这个问题,接下来往下看: 分区和分表: 我们的数据库数据越来越大,随之而

MySQL 大数据量快速插入方法和语句优化

MySQL大数据量快速插入方法和语句优化是本文我们主要要介绍的内容,接下来我们就来一一介绍,希望能够让您有所收获! INSERT语句的速度 插入一个记录需要的时间由下列因素组成,其中的数字表示大约比例: 连接:(3) 发送查询给服务器:(2) 分析查询:(2) 插入记录:(1x记录大小) 插入索引:(1x索引) 关闭:(1) 这不考虑打开表的初始开销,每个并发运行的查询打开. 表的大小以logN (B树)的速度减慢索引的插入. 加快插入的一些方法 如果同时从同一个客户端插入很多行,使用含多个VA

MySQL大数据量分页查询方法及其优化

方法1: 直接使用数据库提供的SQL语句 语句样式: MySQL中,可用如下方法: SELECT * FROM 表名称 LIMIT M,N 适应场景: 适用于数据量较少的情况(元组百/千级) 原因/缺点: 全表扫描,速度会很慢 且 有的数据库结果集返回不稳定(如某次返回1,2,3,另外的一次返回2,1,3). Limit限制的是从结果集的M位置处取出N条输出,其余抛弃. 方法2: 建立主键或唯一索引, 利用索引(假设每页10条) 语句样式: MySQL中,可用如下方法: SELECT * FRO

mysql 大数据分页优化

一.mysql大数据量使用limit分页,随着页码的增大,查询效率越低下. 1.   直接用limit start, count分页语句, 也是我程序中用的方法: select * from product limit start, count当起始页较小时,查询没有性能问题,我们分别看下从10, 100, 1000, 10000开始分页的执行时间(每页取20条), 如下: select * from product limit 10, 20   0.016秒select * from prod

针对MySQL大表优化方案

详解MySQL大表优化方案 (1).字段 (2).索引 (3).规范查询SQL (4).存储引擎 (5).mysql配置参数优化 (6).mysql读写分离 (7).分区和分表 单表优化: 当单表的数据不是一直在暴增,不建议使用拆分,拆分会带来逻辑,部署,运维的各种复杂度,一般以整型值为主的表在千万级以下,字符串为主的表在五百万以下是没有太大问题的.而事实上很多时候MySQL单表的性能依然有不少优化空间,甚至能正常支撑千万级以上的数据量 (1).字段 l 尽量使用TINYINT.SMALLINT

MySQL大数据下Limit使用

对于一直用Oracle的我,今天可是非常诧异,MySQL中同一个函数在不同数量级上的性能居然差距如此之大. 先看表ibmng(id,title,info)  唯一  id key 索引title 先看看两条语句: select * from ibmng limit 1000000,10 select * from ibmng limit 10,10 很多人都会认为不会有多大差别,但是他们都错了,差别太大了,(可能机器不同有点差距,但绝对10倍以上)具体执行时间留给好奇的同学. 这是为什么呢,都是

mysql 大数据 查询方面的测试

---方法1: 直接使用数据库提供的SQL语句---语句样式: MySQL中,可用如下方法: SELECT * FROM 表名称 LIMIT M,N---适应场景: 适用于数据量较少的情况(元组百/千级)---原因/缺点: 全表扫描,速度会很慢 且 有的数据库结果集返回不稳定(如某次返回1,2,3,另外的一次返回2,1,3). Limit限制的是从结果集的M位置处取出N条输出,其余抛弃. ---方法2: 建立主键或唯一索引, 利用索引(假设每页10条)---语句样式: MySQL中,可用如下方法

javaweb学习总结(三十四)——使用JDBC处理MySQL大数据

一.基本概念 大数据也称之为LOB(Large Objects),LOB又分为:clob和blob,clob用于存储大文本,blob用于存储二进制数据,例如图像.声音.二进制文等. 在实际开发中,有时是需要用程序把大文本或二进制数据直接保存到数据库中进行储存的. 对MySQL而言只有blob,而没有clob,mysql存储大文本采用的是Text,Text和blob分别又分为: TINYTEXT.TEXT.MEDIUMTEXT和LONGTEXT TINYBLOB.BLOB.MEDIUMBLOB和L