怎么处理mysql查询量大 mysql查询大量数据( 二 )


跨库join
只要是进行切分,跨节点Join的问题是不可避免的 。但是良好的设计和切分却可以减少此类情况的发生 。解决这一问题的普遍做法是分两次查询实现 。在第一次查询的结果集中找出关联数据的id,根据这些id发起第二次请求得到关联数据 。
跨节点的count,order by,group by以及聚合函数问题
这些是一类问题,因为它们都需要基于全部数据集合进行计算 。多数的代理都不会自动处理合并工作 。解决方案怎么处理mysql查询量大:与解决跨节点join问题的类似,分别在各个节点上得到结果后在应用程序端进行合并 。和join不同的是每个结点的查询可以并行执行,因此很多时候它的速度要比单一大表快很多 。但如果结果集很大 , 对应用程序内存的消耗是一个问题 。
数据迁移 , 容量规划 , 扩容等问题
来自淘宝综合业务平台团队,它利用对2的倍数取余具有向前兼容的特性(如对4取余得1的数对2取余也是1)来分配数据,避免了行级别的数据迁移,但是依然需要进行表级别的迁移,同时对扩容规模和分表数量都有限制 。总得来说,这些方案都不是十分的理想,多多少少都存在一些缺点,这也从一个侧面反映出了Sharding扩容的难度 。
ID问题
一旦数据库被切分到多个物理结点上,我们将不能再依赖数据库自身的主键生成机制 。一方面,某个分区数据库自生成的ID无法保证在全局上是唯一的;另一方面,应用程序在插入数据之前需要先获得ID,以便进行SQL路由.
一些常见的主键生成策略
UUID
使用UUID作主键是最简单的方案 , 但是缺点也是非常明显的 。由于UUID非常的长,除占用大量存储空间外,最主要的问题是在索引上,在建立索引和基于索引进行查询时都存在性能问题 。
Twitter的分布式自增ID算法Snowflake
在分布式系统中,需要生成全局UID的场合还是比较多的,twitter的snowflake解决了这种需求,实现也还是很简单的,除去配置信息,核心代码就是毫秒级时间41位 机器ID 10位 毫秒内序列12位 。
跨分片的排序分页
一般来讲,分页时需要按照指定字段进行排序 。当排序字段就是分片字段的时候,我们通过分片规则可以比较容易定位到指定的分片 , 而当排序字段非分片字段的时候,情况就会变得比较复杂了 。为了最终结果的准确性,我们需要在不同的分片节点中将数据进行排序并返回 , 并将不同分片返回的结果集进行汇总和再次排序,最后再返回给用户 。
mysql 数据量超过百万后怎么处理我们经常会遇到操作一张大表,发现操作时间过长或影响在线业务了,想要回退大表操作的场景 。在我们停止大表操作之后,等待回滚是一个很漫长的过程,尽管你可能对知道一些缩短时间的方法 , 处于对生产环境数据完整性的敬畏,也会选择不做介入 。最终选择不作为的原因大多源于对操作影响的不确定性 。实践出真知,下面针对两种主要提升事务回滚速度的方式进行验证,一种是提升操作可用内存空间,一种是通过停实例 , 禁用 redo 回滚方式进行进行验证 。
仔细阅读过官方手册的同学 , 一定留意到了对于提升大事务回滚效率,官方提供了两种方法:一是增加 innodb_buffer_pool_size 参数大小 , 二是合理利用 innodb_force_recovery=3 参数,跳过事务回滚过程 。第一种方式比较温和,innodb_buffer_pool_size 参数是可以动态调整的,可行性也较高 。第二种方式相较之下较暴力 , 但效果较好 。
两种方式各有自己的优点,第一种方式对线上业务系统影响较?。?不会中断在线业务 。第二种方式效果更显著,会短暂影响业务连续,回滚所有没有提交的事务 。

推荐阅读