您的位置:首页 > 数据库 > MySQL

浅析MYSQL中的分表

2014-06-10 10:08 232 查看
我们知道当数据量大到一定程度 比如超过1000W条数据时 即使有索引 也会使其查询效率等变得低下

举个例子 同样是1亿条数据  查10个1000W的数据表绝对是要对查一个1亿条的数据表要快的

具体的分表分析与介绍 推荐大家看这篇文件MYSQL的3种分表方法与分析

在这里呢 我主要是想给大家分享一篇我在网上看到的介绍MYSQY中MERGE分表的文章 觉得写得比较详细

先简单介绍一下MYSQL中常用的三种引擎的区别

MyISAM引擎

MyISAM引擎是MySQL默认的存储引擎,MyISAM不支持事务和行级锁,所以MyISAM引擎速度很快,性能优秀。MyISAM可以对整张表加锁,支持并发插入,支持全文索引。

如果你不需要事务支持,通常我们建表时都选用MyISAM存储引擎,像新闻表之类都没有必要支持事务。

InnoDB引擎

InnoDB是专为事务设计的存储引擎,支持事务,支持外键,拥有高并发处理能力。但是,InnoDB在创建索引和加载数据时,比MyISAM慢。

涉及到货币操作一般都需要支持事务,什么都能错,钱不能出错。

Memory引擎

内存表,Memory引擎将数据存储在内存中,表结构不是存储在内存中的,查询时不需要执行I/O操作,所以要比MyISAM和InnoDB快很多倍,但是数据库断电或是重启后,表中的数据将会丢失,表结构不会

丢失。如果你需要将SESSION数据存在数据库中,那么使用Memory引擎是个不错的选择。

详细出处参考:http://www.jb51.net/article/37996.htm

一:Merge表的原理及优点

在Mysql数据库中,Merge表有点类似于视图。mysql的merge引擎类型允许你把许多结构相同的表合并为一个表。之后,你可以执行查询,从多个表返回的结果就像从一个表返回的结果一样。每一个合并的表必须有完全相同表的定义和结构。

1.1 Mysql Merge表的优点:

A. 分离静态的和动态的数据

B. 利用结构接近的的数据来优化查询

C. 查询时可以访问更少的数据

D. 更容易维护大数据集

E. 可以通过修改.mrg文件来修改Merge表,当然也可以用alter进行修改,修改后要通过FLUSH
TABLES刷新表缓存,此法可以动态增加减少子表

1.2 merge表存储引擎在如下这种使用场合会最为有用:

1,2,1
网上这样说:
如果需要把日志记录不停的录入MySQL数据库,并且每天、每周或者每个月都创建一个单一的表,而且要制作来自多个表的合计查询,MERGE表这时会非常有效。然而,这项功能有局限性。你只能合并MyISAM表而且必须严格遵守相同的表定义的限制。虽然这看起来好像是一个大问题,但是,如果你使用另外一种表类型(例如InnoDB),这种合并可能就不需要.

1.2.2
我的感觉最直接的用途:
可以把很多表的统计使用一张表来统计,方便我们的统计,例如,统一账户有1000个流水表,如果要用sql来做这个,你会想到什么,是union
吗?当然可以,但是你可以试一下,union时表的个数最大是61个,这样是不是不行了;如果你用merge表那就很简单,就可以在一个表里面做你的统计了(merge表应该也有表的限制,但是我没有找到这个说明),统一账户有1000个表,我创建了4个merge表(之前创建了1个,select是报错“Can't
open file: './uni_acct/t_acct_water_504.frm' (errno: 24)”,然后换成4个,两个其实也可以,哈哈;具体merge表union的表数目限制从测试看应该是503,这个数据不一定准确,只是我的一个测试值(有可能和表的数据量也有关))


merge表的创建和注意事项:

2.1 如何创建merge表

基本表:

CREATE TABLE TEST_MERGE_1(

ID INT(5) NOT NULL,

VALUE VARCHAR(100) NOT NULL,

PRIMARY KEY(ID)

);

CREATE TABLE TEST_MERGE_2(

ID INT(5) NOT NULL,

VALUE VARCHAR(100) NOT NULL,

PRIMARY KEY(ID)

);

MERGE表:

CREATE TABLE TEST_MERGE(

ID INT(5) NOT NULL,

VALUE VARCHAR(100) NOT NULL,

PRIMARY KEY(ID)

) TYPE=MRG_MyISAM INSERT_METHOD=LAST
UNION=(TEST_MERGE_1,TEST_MERGE_2);

2.2 说明:

1. 此表结构必须与基本表完全一致,包括列名、顺序(注意主键,索引这些可以不同)。UNION表必须同属一个DATABASE。

2. 此表类似于SQL中的union机制。

3. 基本表类型必须是MyISAM的。

4.
可以通过修改.mrg文件来修改MERGE表,每个基本表的名字占一行。注意:修改后要通过FLUSH TABLES刷新表缓存。

5. 对基本表的更改可以直接反映在此表上。

6. INSERT_METHOD的取值可以是: 0
不允许插入 FIRST
插入到UNION中的第一个表 LAST
插入到UNION中的最后一个表。(4.0之后可用)

7.
定义在它上面的约束没有任何作用,约束是由基本表控制的,例如两个基本表中存在着同样的一个Key值,那么在MERGE表中会有两个一样的Key值。

2.3
注意:
1.如果是通过修改.mrg文件的方式来修改MERGE表,那么一定要修改后要通过FLUSH
TABLES刷新表缓存,否则修改不会生效。最近犯过一次这样的错误。

2.在数据量、查询量较大的情况下,不要试图使用Merge表来达到类似于Oracle的表分区的功能,会很影响性能。我的感觉是和union几乎等价。

3.查询结果及顺序与创建Merge表时联合表的顺序有关。

看下面的例子:

CREATE TABLE `allentest5` (

`a` int(11) NOT NULL default '0',

`b` varchar(11) default NULL,

PRIMARY KEY (`a`)

) ENGINE=MyISAM DEFAULT CHARSET=latin1

CREATE TABLE `allentest6` (

`a` int(11) NOT NULL default '0',

`b` varchar(11) default NULL,

PRIMARY KEY (`a`)

) ENGINE=MyISAM DEFAULT CHARSET=latin1

CREATE TABLE
`allentest_mrg_5`
(
`a` int(11) NOT NULL default '0',

`b` varchar(11) default NULL,

primary key(a)

)ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`allentest5`,`allentest6`); /*5在前,6在后*/

CREATE TABLE `allentest_mrg_6`

(
`a` int(11) NOT NULL default '0',

`b` varchar(11) default NULL,

primary key(a)

) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`allentest6`,`allentest5`);
/*6在前,5在后*/

CREATE TABLE `allentest_mrg_6_noKey` (

`a` int(11) NOT NULL default '0',

`b` varchar(11) default NULL

) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`allentest6`,`allentest5`) /*meg
没有
主键*/

原始表里面的数据:

select * from allentest5;

+---+---------+

| a | b |

+---+---------+

| 3 | test5_3 |

| 2 | test5_2 |

| 1 | test5_1 |

+---+---------+

select * from allentest6;

+---+---------+

| a | b |

+---+---------+

| 1 | test6_1 |

| 2 | test6_2 |

+---+---------+

几个merger表的结果

select * from
allentest_mrg_6_noKey where a =1; / *没有主键*/

+---+---------+

| a | b |

+---+---------+

| 1 | test6_1 |

| 1 | test5_1 |

+---+---------+

select * from
allentest_mrg_5 where a = 1; /*有主键*/

+---+---------+

| a | b |

+---+---------+

| 1 | test5_1 |

+---+---------+

select * from
allentest_mrg_6 where a = 1; /*有主键*/

+---+---------+

| a | b |

+---+---------+

| 1 | test6_1 |

+---+---------+

select * from
allentest_mrg_5;
+---+---------+

| a | b |

+---+---------+

| 3 | test5_3 |

| 2 | test5_2 |

| 1 | test5_1 |

| 1 | test6_1 |

| 2 | test6_2 |

+---+---------+

select * from allentest_mrg_6;

+---+---------+

| a | b |

+---+---------+

| 1 | test6_1 |

| 2 | test6_2 |

| 3 | test5_3 |

| 2 | test5_2 |

| 1 | test5_1 |

+---+---------+

select * from
allentest_mrg_6_noKey;
+---+---------+

| a | b |

+---+---------+

| 1 | test6_1 |

| 2 | test6_2 |

| 3 | test5_3 |

| 2 | test5_2 |

| 1 | test5_1 |

+---+---------+

可以看到如下信息:

1)
mrg表查询的结果和 union的表顺序一致(见select
* from allentest_mrg_5;和select * from allentest_mrg_6;);

2)mrg主键的问题;a.在查询时如果不带条件,这时候查询出来的数据和没有带主键的是一样的(见select
* from allentest_mrg_6; 和
select * from allentest_mrg_6_noKey;);b.如果带条件(带有主键的查询),这样之后查询到第一个带有主键的内容(见select
* from allentest_mrg_6_noKey where a =1; select * from
allentest_mrg_5 where a = 1; 和
select * from allentest_mrg_6 where a = 1;)
;因此如果是做统计,那么在创建mrg表时尽量不要增加主键
原文链接:http://blog.chinaunix.net/uid-24532607-id-3495621.html


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: