首页 > 其他分享 >大数据量实时统计排序分页查询(并发数较小时)

大数据量实时统计排序分页查询(并发数较小时)

时间:2023-03-22 15:03:34浏览次数:44  
标签:count web 并发 数据库 数较 数据量 sql 排序 id


大数据量实时统计排序分页查询的瓶颈不是函数(count,sum等)执行,

不是having, 也不是order by,甚至不是表join, 导致慢的原因就在于“数据量太大本身”

 

  1. 化整为零

就是将表划分为M份相互独立的部分,可以是分表,也可以是不分表但冗余一个取模结果字段

实际结果是不分表比分表更加灵活,只需稍加配置,就可以动态切分大表,随意更改M的大小。

 

将1条慢sql(大于30秒)拆分成为N条查询速度巨快的sql(单条sql执行时间控制在20毫秒以内)

然后再web应用中以适当的线程数去并发查询这些执行时间快的N条小sql再汇总结果

 

  1. 两步查询

第一步查询中去并发执行这N条小sql, 只取排序字段和标识字段,其他字段一律丢弃

汇总结果后定位出当前页面要显示的pageNum条数据,再进行第二步查询,取出页面上需要展示的所有字段

 

  1. web应用自身计算与数据库计算的折中

PS:这一点是至关重要的,其他几点都可以不看,这点是最关键的。慢慢解释一下:

有三种方式统计所有的记录,

a)         第一种方式是把数据库中所有记录(只取排序字段和标识字段并且不做任何sum,count having order by等操作)

全部拉到web应用中,在web应用中完成所有的计算

b)         第二种方式是把数据库中所有记录做sum count having等操作之后的所有行数拉到web应用中,在web应用中完成剩余计算

c)         第三种方式是把数据库中所有记录做sum count having order by等操作之后把limit后的数据拉到web应用中,

在web应用中对limit后的数据再计算

 

显然,第一种方式 数据库什么活都不做只取数据 是不可行的。以lg_order_count_seller为例,1500万行,

如果只算id, seller_id和order_count 这三个bigint类型,至少需要拉8*3*1500 0000 = 360000000=340M,

拉到内存中之后存储需要8*4*15000000= 460M,这还不算List是的2的n次方这个特点和计算排序等的内存开销,

不仅数据库与web应用机器IO扛不住,就是应用自身恐怕也要OOM了。

 

第二种方式,所有记录做sum count having等操作之后,由于是group by seller_id的,总得数据量变为100万(就是卖家总数),

这样子一来,共需要拉8*3*100 0000 = 23M,拉到内存之后,需要8*4*100 0000 = 30M, 再算上List是的2的n次方这个特点和

计算排序等的内存开销也不会超过100M, IO的时间和内存开销勉强可以考虑接受。

 

第三种方式,所有记录做sum count having order by等操作之后把limit后的数据拉到web应用中,因为做了limit,所以,

数据量很小了,无论是IO还是内存开销都已经很小了。可以忽略。

 

综合以上三种,第三种方式适用于页面的前n页和后n页,因为这个limit的数据量随着页数的增大而增大,

当大到每个切分后的小表的数据量时就转为第二种方式了。

第二种方式适用于页面的第[n+1, totaoPageNum-n]页。

  1. 切分成N条小sql后并行执行时排序不稳定性的解决办法

① 问题描述:

 

优化之前,还是是一条大慢sql查询时,由于数据库排序是稳定排序,

所以当两条记录排序字段值相同时他们在页面上的页码位置是固定的。

 

优化之后,当并行执行这N条小sql时,由于无法控制这些小sql的先后执行顺序,

导致在web应用中当两条记录的排序字段值相同时在页面上的页码位置是随机的。

 

② 解决办法:

除了拉标识字段(seller_id)和排序字段(order_count_sum)之外,再取一个unique(id)的字段,当两条记录的排序字段值相同时,

再用这个unique的字段(在卖家监控中这个字段是id)进行第二次排序.这样就解决了排序不稳定的问题。

   

③ 也许,看到这里会有疑问,为什么不用seller_id?seller_id也是唯一, 这样子不是少取id这个字段,减少IO了?

seller_id虽然也是唯一,可以辅助排序,但是不要忘记数据库的排序规则是:

如果两列的值相等,那么序号在前的排在前面,这里的序号就是主键(自动生成,autoincrement),

如果用seller_id的话还是不能保证排序的稳定性,只能用主键id.

 

  1. 优先加载页面上的主要元素,然后再去异步加载次要元素,

把数据库的连接,扫表,计算等资源优先让给用户关注的主要元素,次要元素可等主要元素加载完成之后再加载。

反应在卖家监控页面中,查数据和查页页码的sql语句基本相同,是在竞争同一资源,

所以,需要做一个策略,优先把资源让给查数,数据查完之后再去查页码。

 

  1. 限流

由于多线程取数据并没有从本质上提高数据库性能,所以必须针对大数据量实时统计排序分页查询做限流

我这里打个比方:食堂有6个窗口,物流团队吃饭要买6个菜,平均每买1个菜需要1分钟的时间,

如果派我一个人去一个窗口买的话需要6分钟的时间

假如派6个人分别去6个窗口买这6个菜,只需要1分钟的时间

但是,如果除了物流团队,再来其他5个团队呢,也就是说6个团队每个团队买6个菜共买36个菜,

这样子有的团队先买完,有的团队后买完,但平均时间还是6分钟。本质上没有变化。

   所以,对于特定的查询条件,必须进行限流。让每分钟至多有6个团队买菜,这样子能使得情况变得不至于太糟糕。

 

  1. 从根本上改变现状

这一点从目前来看只能是展望了,比如mysql数据库换更为强大的oracle数据库,

或更换InnoDb引擎为其他,或更换SATA硬盘为SSD 。。。。。。

 

 

  1. 从实践效果来看,优化后的效果是很明显的。

标签:count,web,并发,数据库,数较,数据量,sql,排序,id
From: https://blog.51cto.com/u_2650279/6142635

相关文章

  • Java并发夺命50问
    本文已经收录到Github仓库,该仓库包含计算机基础、Java基础、多线程、JVM、数据库、Redis、Spring、Mybatis、SpringMVC、SpringBoot、分布式、微服务、设计模式、架构、校......
  • Go 并发编程(二):锁、Select、Context、定时器
    目录Sync(锁)sync.WaitGroupsync.Oncesync.Lock:锁sync.Mutex:互斥锁sync.RWMutex:读写锁死锁sync.Map:并发安全Mapsync.Atomic:原子操作SelectSelect是什么?Select使用空select......
  • tcp网络编程4—并发的io多路复用实现(fcntl非阻塞)
    fcnt_vector_fd.h#ifndef_FCNTL_VECTOR_FD_H#define_FCNTL_VECTOR_FD_Htypedefstruct{int*fd;intconter;intmax_conter;}VectorFd;extern......
  • 【python】多线程并发,rpc接口性能测试
    1、官方文档https://docs.python.org/3/library/concurrent.futures.html 2、安装python3.x中自带了concurrent.futures模块python2.7需要安装futures模块,使用命令......
  • 性能测试中如何使用RunnerGo还原混合并发场景
    我们在进行软件开发时经常需要进行性能测试、压力测试和负载测试。其中有一类测试场景叫做混合并发测试,需要模拟多个接口下不同数量的用户使用场景,检查同时处理多个并发任务......
  • Apache Jmeter进行curl请求并发测试
    1、按照截图顺序进行新建(新建线程组) 2、在新建的线程组中右键添加 3、添加相关协议、IP、端口、HTTP请求形式{"jsonrpc":"2.0","method":"eth_sendTransaction","params......
  • 使用shell并发执行系统命令
    一解决方案旧方案为挨个执行shell_exec,串行执行,虽然执行很快,奈何监听命令众多,redis连接有等待时间等,有的还需要执行多次取平均值,所以执行完已超过1min故,改为并发执行命......
  • 二级菜单、多个Ajax请求的并发执行
    二级菜单     多个Ajax请求的并发执行     ......
  • 计算并发用户数五种方法
    https://blog.csdn.net/MENG_Q_Z/article/details/125034279 一、经典公式1:  一般来说,利用以下经验公式进行估算系统平均并发用户数和峰值: 1)平均并发用户数 C=......
  • 高并发高可用架构设计之LVS
    LVS简介        LVS的英文全称是LinuxVirtualServer,即Linux虚拟服务器。它是我们国家的章文嵩博士的一个开源项目。在linux内核2.6中,它已经成为内核的一部分,在......