首先将存储引擎限定在innodb
如果将不同的表分到多个库多个机器上,那一定是能提升性能的,毕竟你花钱买机器了,总的可用CPU和内存高了.这种情况不必考虑.
如果所有分表都在同库同机器上,每个表的查询都共用CPU和内存,性能是怎么提升的?
例如这条查询 select * from user_feeds where uid = ? ,且uid字段上有二级索引,查询步骤为:
来看一下分表后的查询成本:
好了,全部的有二级索引的情况,如果没有索引,需要全表扫描时,扫描整个聚簇索引的成本: 加载数据页到内存的IO次数(聚簇索引的页面数)、扫描记录的CPU占用(整个聚簇索引的记录数量) .分表以后所有表总的记录数量不变,页面数量也可以认为不变.所以全表扫描的查询性能分表与不分表也不会有什么差别.
垂直分表,表记录数不会改变,每条记录数据占用空间会变小,从而导致单表聚簇索引每个数据页可以存储的记录变多,聚簇索引的数据页数量变少,原来uid=X的记录可能分布在N个数据页上,分表后uid=X的记录分布在的数据页数量=N.也就是减少回表IO的次数.
但是,这种情况只限于合理的垂直分表,也就是select的列可以落在同一张表中.
索引列:uid、created_at
与理论估算相近
分库分表是MYSQL应对大数据、高并发的常见解决方案,有很多朋友特别是熟悉ORACLE的朋友可能会问,
MYSQL有分区表,分区表同样能达到IO分散、提高性能的目的,而且更简单,更方便,为何还要采用分库分表呢.
我想主要有以下几个方便的原因:
①.、MYSQL 对多CPU的支持还不是很好,还不能充分发挥多CPU的能力,如不支持并行,很多东西都不支持在线DDL等,
?如果将分表数据堆积成分区表,即便IO不是问题,MYSQL自身管理上也是个问题,效率比分表差太多.? ?
?甚至不能在有限的时间窗口内完成备份.
所以,现在很多的互联网公司的一些互联网应用,很少有采用分区表的,而大都采用分库分表.
分表是分散数据库压力的好方法.
分表,最直白的意思,就是将一个表结构分为多个表,然后,可以再同一个库里,也可以放到不同的库.
当然,首先要知道什么情况下,才需要分表.个人觉得单表记录条数达到百万到千万级别时就要使用分表了.
分表的分类
**1、纵向分表**
将本来可以在同一个表的内容,人为划分为多个表.(所谓的本来,是指按照关系型数据库的第三范式要求,是应该在同一个表的.)
分表理由:根据数据的活跃度进行分离,(因为不同活跃的数据,处理方式是不同的)
案例:
这样纵向分表后:
首先存储引擎的使用不同,冷数据使用MyIsam 可以有更好的查询数据.活跃数据,可以使用Innodb ,可以有更好的更新速度.
其次,对冷数据进行更多的从库配置,因为更多的操作时查询,这样来加快查询速度.对热数据,可以相对有更多的主库的横向分表处理.
其实,对于一些特殊的活跃数据,也可以考虑使用memcache ,redis之类的缓存,等累计到一定量再去更新数据库.或者mongodb 一类的nosql 数据库,这里只是举例,就先不说这个.
分表理由:根据数据量的规模来划分,保证单表的容量不会太大,从而来保证单表的查询等处理能力.
案例:同上面的例子,博客系统.当博客的量达到很大时候,就应该采取横向分割来降低每个单表的压力,来提升性能.例如博客的冷数据表,假如分为100个表,当同时有100万个用户在浏览时,如果是单表的话,会进行100万次请求,而现在分表后,就可能是每个表进行1万个数据的请求(因为,不可能绝对的平均,只是假设),这样压力就降低了很多很多.
延伸:为什么要分表和分区?
日常开发中我们经常会遇到大表的情况,所谓的大表是指存储了百万级乃至千万级条记录的表.这样的表过于庞大,导致数据库在查询和插入的时候耗时太长,性能低下,如果涉及联合查询的情况,性能会更加糟糕.分表和表分区的目的就是减少数据库的负担,提高数据库的效率,通常点来讲就是提高表的增删改查效率.
什么是分表?
分表是将一个大表按照一定的规则分解成多张具有独立存储空间的实体表,我们可以称为子表,每个表都对应三个文件,MYD数据文件,.MYI索引文件,.frm表结构文件.这些子表可以分布在同一块磁盘上,也可以在不同的机器上.app读写的时候根据事先定义好的规则得到对应的子表名,然后去操作它.
什么是分区?
分区和分表相似,都是按照规则分解表.不同在于分表将大表分解为若干个独立的实体表,而分区是将数据分段划分在多个位置存放,可以是同一块磁盘也可以在不同的机器.分区后,表面上还是一张表,但数据散列到多个位置了.app读写的时候操作的还是大表名字,db自动去组织分区的数据.
**MySQL分表和分区有什么联系呢?**
①.、都能提高mysql的性高,在高并发状态下都有一个良好的表现.
我们知道对于大型的互联网应用,数据库单表的数据量可能达到千万甚至上亿级别,同时面临这高并发的压力.Master-Slave结构只能对数据库的读能力进行扩展,写操作还是集中在Master中,Master并不能无限制的挂接Slave库,如果需要对数据库的吞吐能力进行进一步的扩展,可以考虑采用分库分表的策略.
**1、分表**
在分表之前,首先要选中合适的分表策略(以哪个字典为分表字段,需要将数据分为多少张表),使数据能够均衡的分布在多张表中,并且不影响正常的查询.在企业级应用中,往往使用org_id(组织主键)做为分表字段,在互联网应用中往往是userid.在确定分表策略后,当数据进行存储及查询时,需要确定到哪张表里去查找数据,
数据存放的数据表 = 分表字段的内容 % 分表数量
分表能够解决单表数据量过大带来的查询效率下降的问题,但是不能给数据库的并发访问带来质的提升,面对高并发的写访问,当Master无法承担高并发的写入请求时,不管如何扩展Slave服务器,都没有意义了.我们通过对数据库进行拆分,来提高数据库的写入能力,即所谓的分库.分库采用对关键字取模的方式,对数据库进行路由.
数据存放的数据库=分库字段的内容%数据库的数量
数据库分表可以解决单表海量数据的查询性能问题,分库可以解决单台数据库的并发访问压力问题.
当数据库同时面临海量数据存储和高并发访问的时候,需要同时采取分表和分库策略.一般分表分库策略如下:
中间变量 = 关键字%(数据库数量*单库数据表数量)
库 = 取整(中间变量/单库数据表数量)
表 = (中间变量%单库数据表数量)
实例:
①.、分库分表
复制代码 代码如下:
php
for($i=0;$i 100; $i++ ){
";
echo "INSERT INTO members{$i} SELECT * FROM members WHERE mid0={$i}
}
同样还是members表,前期设计的表结构不尽合理,随着数据库不断运行,其冗余数据也是增长巨大,同事使用了下面的方法来处理:
先创建一个临时表:
/*创建临时表*/
CREATE TABLE members_tmp LIKE members
接着重命名将新表替换上去:
/*这是个颇为经典的语句哈*/
RENAME TABLE members TO members_bak,members_tmp TO members;
以上就是土嘎嘎小编大虾米为大家整理的相关主题介绍,如果您觉得小编更新的文章只要能对粉丝们有用,就是我们最大的鼓励和动力,不要忘记讲本站分享给您身边的朋友哦!!