Mysql某个表有近千万数据,CRUD比较慢,如何优化?( 二 )


跨节点的count,order by,group by以及聚合函数问题
这些是一类问题 , 因为它们都需要基于全部数据集合进行计算 。多数的代理都不会自动处理合并工作 。解决方案:与解决跨节点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位 。
跨分片的排序分页
一般来讲 , 分页时需要按照指定字段进行排序 。当排序字段就是分片字段的时候 , 我们通过分片规则可以比较容易定位到指定的分片 , 而当排序字段非分片字段的时候 , 情况就会变得比较复杂了 。为了最终结果的准确性 , 我们需要在不同的分片节点中将数据进行排序并返回 , 并将不同分片返回的结果集进行汇总和再次排序 , 最后再返回给用户 。




推荐阅读