“ShardingCore”是如何针对分表下的分页进行优化的

首先还是要给自己的开原框架打个广告 sharding-core 针对efcore 2+版本的分表组件,首先我们来快速回顾下目前市面上分表下针对分页常见的集中解决方案

分表解决方案

解决方案skip<=100skip<10000skip>10000优点缺点
内存分表速度快O(n),n=skip*分表数速度快O(n),n=skip*分表数,内存暴涨O(n),n=skip*分表数,内存爆炸,速度越来越慢实现简单,支持分库skip过大内存暴涨
union all速度快速度一般死慢死慢的实现简单仅支持同库,不好优化,索引会失效
流式分表速度快O(n),n=skip速度快O(n),n=skipO(n),n=skip 速度越来越慢支持分库实现复杂

1.内存分页

顾名思义就是将各个表的结果集合并到内存中进行排序后分页

2.union all

使用的是数据库本身的聚合操作,用过匿名表来实现和操作当前表一样无感知

3.流式分表

和名字一样就是通过next来一次一次获取,和datareader类似只有在next后才可以获取到客户端

通过上面的简单对照我们可以清楚地发现,其实我们可以选择的基本上就内存分表和流式分表而已,又以为内存分表的限制其实最优解就是流式分表。
上篇文章我们简单的介绍了流式分表这次我们在针对流式分表的原理进行介绍,并且提出针对流式分表下的分页“最优解”。

流式分表原理

我们先简单的假设一个场景,我们有一个订单表,针对订单表我们进行了分表,根据订单的创建时间按月分表。
如果我们执行 select * from order limit 100,2

内存分页

在这种情况下如果我们需要分页跳过前 100条记录获取第101-102条记录,现在如果内存分表情况下我们该如何操作

流式分页

上述就是内存排序的实现,通过上图发现我们需要获取102*3条数据,并且进行排序后获取第101和102条数据,所以说上述表格里已经体现了内存分表的优劣 那么如果是流式分页我们是如何操作的呢

简单解释下这张图,右边为数据库在数据库外面的分别是next了一次的数据,其他数据都是在数据库里面只是结果集有了但是结果还不没有取到client,
通过100次next后我们可以取到真实的数据所以对于任何分页都是只需要O(n)的时间复杂度,其中n=skip+take就是跳过多少条和获取多少条
注意:不要以为next了100次就是查询了100次数据库,结果集生成后就不会再查询数据库里,next可以理解为是对结果集的客户端获取。

sharding-core的优化

至此流式分表获取数据的原理基本上就是这样,针对这种情况下我们该如何进行对分页数据进行优化,因为上图数据库模块内部的区域是未知的也就是说我们是不知道索引“1”后面的索引“2”和其他语句下的当前索引大小情况,我们只知道索引“1”和索引“2”在本张表里面的排序情况,
针对这种情况我们应该是没办法进行程序的优化了,可以理解为目前情况下已经是最优解了。但是如果我们仔细一想可以发现事情并不简单

大家能看懂吗我们只需要让程序的获取方式按顺序那么就可以保证性能最佳 O(1),所以针对时间分表或者顺序分表的情况下我们一般情况下使用时间倒序或者顺序,那么就可以告诉程序如何排序,又可以得知,在对应顺序的情况下每张表都是顺序的又因为只要保证如下就可以了

有些朋友可能会有疑问,为什么order by id也可以这样,其实order by id是不可以这样的,但是如果你这样又会怎么样?难道数据库用它最优解排序返回是正确,程序用最优解排序返回就不是正确了?

sharding-core的优化升阶

可能有些喷友认为优化到这里就是差不多了但是其实sharding-core针对优化还不止如此,
因为这种排序需要让程序知道以某种情况排序可以按表顺序排序达到性能最优,但是如果我是Id取模或者范围就会导致这个排序仅仅只适合id排序如果需要按别的来排序就没办法了还是得走流式分表.
那么该如何优化呢还是一样我们忽略了分页是2步操作

这种排序仅仅需要的是第一存在order by 第二告诉系统skip多少后需要启用反排,并且该情况适用于任何的分表规则id取模或者别的其他情况都是可以支持的

你以为sharding-core的优化结束了吗?

sharding-core已经实现了以上所有的解决方案,并且已经在实现第三种优化,就是极不规则情况下的分页,具体就是当表查询坐落到3张表后其中2张表或者1张表的count极少的情况下直接取到内存然后剩余的1张表可以直接通过skip+take获取数据后内存排序,
因为时间原因目前还没实现后续会针对这个情况进行实现。
以上就是我为大家带来的理论和干货,
具体的理论听得爽了干货我再发一遍吧 sharding-core

sharding-core如何启用高性能分页

高性能分页

sharding-core本身使用流式处理获取数据在普通情况下和单表的差距基本没有,但是在分页跳过X页后,性能会随着X的增大而减小O(n)
目前该框架已经实现了一套高性能分页可以根据用户配置,实现分页功能。

支持版本x.2.0.16+

1.如何开启分页配置 比如我们针对用户月新表进行分页配置,先实现IPaginationConfiguration<>接口,该接口是分页配置接口

public class SysUserSalaryPaginationConfiguration:IPaginationConfiguration<SysUserSalary>{public void Configure(PaginationBuilder<SysUserSalary> builder){builder.PaginationSequence(o => o.Id).UseTailCompare(Comparer<string>.Default).UseQueryMatch(PaginationMatchEnum.Owner | PaginationMatchEnum.Named | PaginationMatchEnum.PrimaryMatch);builder.PaginationSequence(o => o.DateOfMonth).UseQueryMatch(PaginationMatchEnum.Owner | PaginationMatchEnum.Named | PaginationMatchEnum.PrimaryMatch).UseAppendIfOrderNone(10);builder.PaginationSequence(o => o.Salary).UseQueryMatch(PaginationMatchEnum.Owner | PaginationMatchEnum.Named | PaginationMatchEnum.PrimaryMatch).UseAppendIfOrderNone();builder.ConfigReverseShardingPage(0.5d,10000L);}}

2.添加配置
在对应的用户月薪路由中添加配置

        public override IPaginationConfiguration<SysUserSalary> CreatePaginationConfiguration(){return new SysUserSalaryPaginationConfiguration();}

3.Configure内部为什么意思?

  1. builder.PaginationSequence(o => o.Id) 配置当分页orderby 字段为Id时那么分表所对应的表结构为顺序,顺序的规则通过UseTailCompare来设置,其中string为表tail,
    具体什么意思就是说如果本次分页设计3张表分别是table1,table2,table3,如果我没配置id的情况下那么需要查询3张表然后分别进行流式聚合,如果我配置了id的情况下,如果本次sql查询带上了id作为order by字段
    那么就不需要分别查询3张表,可以直接查询table1如果table1的count大于你要跳过的页数,假设分页查询先查询多少条,table1:100条,table2:200条,table3:300条
    如果你要跳过90条获取10条原先的时间就是O(100)现在的时间就是O(10)因为table1跳过了90条还剩余10条;

  2. UseQueryMatch是什么意思,这个就是表示你要匹配的规则,是必须是当前这个类下的属性还是说只需要排序名称一样即可,因为有可能select new{}匿名对象类型就会不一样,PrimaryMatch表示是否只需要第一个主要的
    orderby匹配上就行了,UseAppendIfOrderNone表示是否需要开启在没有对应order查询条件的前提下添加本属性排序,这样可以保证顺序排序性能最优

  3. builder.ConfigReverseShardingPage 表示是否需要启用反向排序,因为正向排序在skip过多后会导致需要跳过的数据过多,尤其是最后几页,如果开启其实最后几页就是前几页的反向排序,其中第一个参数表示跳过的因子,就是说
    skip必须大于分页总total*该因子(0-1的double),第二个参数表示最少需要total多少条必须同时满足两个条件才会开启(必须大于500),并且反向排序优先级低于顺序排序,
    4.如何使用

var shardingPageResultAsync = await _defaultTableDbContext.Set<SysUserMod>().OrderBy(o=>o.Age).ToShardingPageAsync(pageIndex, pageSize);

注意:如果你是按时间排序无论何种排序建议开启并且加上时间顺序排序,如果你是取模或者自定义分表,建议将Id作为顺序排序,如果没有特殊情况请使用id排序并且加上反向排序作为性能优化

测试

首先我们使用 EFCore.BulkExtensions
本机环境 AMD3900X 12核24线程,32GDDR4 3200内存 980pro固态 sqlserver2012
针对数据进行创建

一共近295.5w数据耗时24.2秒其中解析表路由耗时3.4秒,插入到本地20.8秒,实际300w订单肯定要比这个时间长因为测试原因所以创建的订单表字段比较少
再不起用高性能分表的情况下我们看下

流式分页


基本在skip 1w后还是可以保持在500ms,skip2w后虽然内存波动不大但是基本上耗时也有显著增加那么如果开启了高性能分表呢

高性能分页




直接爆杀有没有

如果需要使用请在nuget安装ShardingCore记得勾选预览版本哦安装最新版

最后的最后

如果本文章对您有帮助请点下推荐,如果本框架对您有帮助请点下start,Thanks♪(・ω・)ノ github sharding-core:https://github.com/xuejmnet/sharding-core

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/298409.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

docker pull 私有_【赵强老师】管理Docker镜像

一、什么是Docker的镜像Docker 是一个开源的应用容器引擎&#xff0c;让开发者可以打包他们的应用以及依赖包到一个可移植的容器中&#xff0c;然后发布到任何流行的Linux机器上&#xff0c;也可以实现虚拟化&#xff0c;容器是完全使用沙箱机制&#xff0c;相互之间不会有任何…

看着女朋友的肚子,以肉眼可见的速度大起来......

1 女生的肚子有多神奇▼2 你的论文除了导师真没人想要▼3 脑子&#xff1a;各部门注意&#xff01;这次一定可以&#xff01;手&#xff1a;&#xff1f;&#xff1f;&#xff1f;▼4 这孩子可能是高估了自己的大长腿▼5 到处说前男友死了算违法吗&#xff1f;▼6 男人妖…

违反GPL协议,法院判罚了!国内首例

整理 | 一君出品 | OSC开源社区&#xff08;ID&#xff1a;oschina2013&#xff09;近日&#xff0c;一起关于 GPL 版权纠纷案裁判文书公示。一审判决书显示&#xff0c;GPL3.0 协议是一种民事法律行为&#xff0c;具有合同性质&#xff0c;可认定为授权人与用户间订立的著作权…

开篇 — 【面向对象设计模式学习】

说明&#xff1a; 关于设计模式的文章网上已经很多了&#xff0c;本人也只是想参考别人的文章来系统地学习一下设计模式&#xff0c;因此&#xff0c;这个系列并不是一个系列教程&#xff0c;而仅仅是作为本人学习设计模式的一个学习笔记&#xff0c;此外&#xff0c;由于本人能…

又来了!深度学习PyTorch与TensorFlow到底哪家强?

全世界只有3.14 % 的人关注了爆炸吧知识自从2012年深度学习再一次声名鹊起以来&#xff0c;许多机器学习框架都争先恐后地要成为研究人员和行业从业者的新宠。面对如些众多的选择&#xff0c;人们很难判断最流行的框架到底是什么。在某些情况下&#xff0c;深度学习或深度迁移学…

mysql从多个表查询数据类型_MySQL 之 多表查询

阅读目录一.多表联合查询#创建部门CREATE TABLE IF NOT EXISTSdept (didint not null auto_increment PRIMARY KEY,dnameVARCHAR(50) not null COMMENT 部门名称)ENGINEINNODB DEFAULTcharset utf8;#添加部门数据INSERT INTO dept VALUES (1, 教学部);INSERT INTO dept VALUES …

通过 GitExtensions 来使用 Git 子模块功能

通过 GitExtensions 来使用 Git 子模块功能目录一、前言二、Git 子模块三、子模块更改提交四、更新子模块五、[附] 去除最近的提交记录独立观察员 2021 年 9 月 5 日一、前言众所周知&#xff0c;编程&#xff0c;尤其是面向对象编程的一个重要思想就是 “封装”&#xff0c;可…

Linux系列-Red Hat5平台下的Postfix邮件服务搭建(二)

咱们接着上次的说&#xff0c;本次没有小标题。想了半天也没想出个好名子来&#xff0c;因为这次我们要做三件事&#xff1a;1.搭建基于Postfix的webmail&#xff1b;2.设置用户别名和邮件群组&#xff1b;3.设置邮件大小、邮箱空间的限制。环境还是之前的&#xff0c;做之前可…

单片机断电后静态存储区里面还有数据吗_单片机启动流程和存储架构详解

最近在给公司的ADAS DCU做内存分配&#xff08;Memory Allocation&#xff09;&#xff0c;在这儿记录一下相关知识点&#xff0c;也算是给中文社区做贡献了。目录&#xff1a;1. ECU启动流程2. 存储空间解析3. TC397单片机的Memory Map和一些备注1. ECU启动流程图总比文字直观…

培养有见识的孩子,这6部适合孩子的纪录片,在家也能涨知识!

全世界只有3.14 % 的人关注了爆炸吧知识对孩子来说&#xff0c;好的纪录片就像打开了一扇新世界的大门&#xff0c;让他们了解更多世界的奇妙之处。BBC&#xff08;英国广播公司&#xff09;的纪录片题材广泛、制作精良。看这些经典的纪录片&#xff0c;既可以追溯上下数千年的…

Beta版本发布报告

项目名称学霸系统写手机客户端项目版本Beta版本负责人北京航空航天大学计算机学院 hots团队联系方式http://www.cnblogs.com/hotsbuaa/要求发布日期2014-12-28第一阶段基本功能已经完成&#xff0c;因此第二阶段的任务是&#xff1a;美化UI&#xff0c;修复接口&#xff0c;修复…

Dapr牵手.NET学习笔记:开篇

dapr&#xff0c;一个为分布式应用程序的运行时&#xff0c;为开发者在对接分布式组件时&#xff0c;提供了便利。使用dapr带来的好处可扩展性&#xff0c;因为它是通过sidecar的理概念来集成其他运行时的。同时dapr还提供了多种语言的SDK。关于dapr更多介绍&#xff0c;官方文…

vue 一个页面有点请求需要同时发送_前端性能优化,这些你都需要知道

来源: 海洋里的魔鬼鱼前言最近花了一些时间在项目的性能优化上&#xff0c;背后做了很多工作&#xff0c;但是最后依然没有达到自己想要的结果&#xff0c;有些失望&#xff0c;但是还是记录下自己的执着。性能优化总结&#xff1a;减少请求次数、减小资源大小、提高响应和加载…

男人能有什么错呢?

1 这上菜方式厉害了&#xff01;2 谁上学的时候还没转过笔了&#xff01;3 和朋友的塑料友情 图自别叫我P图仔4 非洲最致命的猫&#xff01;传说能撂倒长颈鹿&#xff01;大家估量一下&#xff01;5 狗子&#xff1a;你放开我好吗&#xff1f;&#xff1f;6 这位小姐姐真的很酷…

H3C 5510 交换机DHCP设置

DHCP不能发现网络上非DHCP客户机已经在使用的IP地址&#xff1b;当网络上存在多个DHCP服务器时&#xff0c;一个DHCP服务器不能查出已被其它服务器租出去的IP地址&#xff1b;DHCP服务器不能跨路由器与客户机通信&#xff0c;除非路由器允许BOOTP转发。PC发出的广播包&#xff…

opentrace在mysql中使用_采用OpenReplicator解析MySQL binlog

Open Replicator是一个用Java编写的MySQL binlog分析程序。Open Replicator 首先连接到MySQL(就像一个普通的MySQL Slave一样)&#xff0c;然后接收和分析binlog&#xff0c;最终将分析得出的binlog events以回调的方式通知应用。Open Replicator可以被应用到MySQL数据变化的实…

雷军:有人说我写的代码像诗一样优雅~

全世界只有3.14 % 的人关注了爆炸吧知识整合整理&#xff1a;程序员的那些事&#xff08;id&#xff1a;iProgrammer&#xff09;雷军的代码像诗一样优雅↓↓↓有些网友在评论中质疑&#xff0c;说雷军代码不会是「屎」一样优雅吧。说这话的网友&#xff0c;也许是开玩笑的&…

mysql分析日志_MYSQL 索引(三)--- SQL日志分析

慢查询日志Mysql 的慢查询日志是 Myql 提供的一种日志记录&#xff0c;用来记录在 Myql 中响应时间查过阈值的语句&#xff0c;具体指运行时间超过 long_query_time 值的 SQL&#xff0c;则会被记录在日志中。long_query_time 默认为 10&#xff0c;单位为秒。默认情况下&#…

C#多线程开发-任务并行库

你好&#xff0c;我是阿辉。正文共2090字&#xff0c;预计阅读时间&#xff1a;6min。之前学习了线程池&#xff0c;知道了它有很多好处。使用线程池可以使我们在减少并行度花销时节省操作系统资源。可认为线程池是一个抽象层&#xff0c;其向程序员隐藏了使用线程的细节&#…

为什么数学不好,和语文有关系?

▲ 点击查看苏步青教授在担任复旦大学校长时曾经说过:“如果允许复旦大学单独招生考试&#xff0c;我的意见是第一堂课就考语文&#xff0c;考后就批卷子。不合格的&#xff0c;以下的功课就不要考了。语文你都不行&#xff0c;别的是学不通的。”苏步青作为享誉世界的数学家&a…