`
wbj0110
  • 浏览: 1602732 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

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

阅读更多

大数据量实时统计排序分页查询的瓶颈不是函数(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. 从实践效果来看,优化后的效果是很明显的。
分享到:
评论

相关推荐

    大数据量翻页查询的一点经验

    在大数据量的翻页查询中,优化查询性能是至关重要的,因为这直接影响到系统的响应速度和用户体验。在本文中,我们将探讨如何针对特定场景优化这种查询。首先,我们需要理解系统的基本设定:每天生成一张包含1000万条...

    大数据量时提高分页的效率

    然而,这种方式并不适用于大数据量,因为它每次加载时都会从数据库中获取所有数据,这在数据量大或并发用户多的情况下会导致性能瓶颈。因此,我们需要转向自定义分页,这是一种更高效的方法,它仅从数据库中检索当前...

    java多线程查询数据库

    在Java编程中,多线程查询数据库是一种常见的优化策略,特别是在处理大数据量或者需要并行执行多个查询时。本文将详细探讨如何利用Java的多线程技术和线程池来实现并发查询数据库,以及相关的文件`BatchDataUtil....

    数据更新与分页数据更新与分页数据更新与分页

    在Web应用中,当数据集过大时,分页可以将数据分割成多个较小的部分,每次只加载一部分到用户界面。这通常通过LIMIT和OFFSET SQL子句实现。例如,要获取第2页(每页10条记录)的数据,可以写: ```sql SELECT * ...

    sybase分页代码使用jdbc分页速度快适合大数据

    分页是将大结果集分割成较小的部分,每次只返回一部分数据,通常由页码和每页记录数来定义。在Sybase中,可以使用SQL的`LIMIT`或`TOP`关键字配合`OFFSET`来实现分页。然而,JDBC并不直接支持`LIMIT`和`OFFSET`,因此...

    千万级分页存储过程 实现对表的数据分页 速度非常快

    在IT领域,尤其是在数据库管理与优化方面,千万级数据分页技术是处理大数据量时不可或缺的一项技能。本文将深入解析“千万级分页存储过程实现对表的数据分页速度非常快”的核心知识点,包括其原理、实现方法以及SQL ...

    不使用pageHelper在java项目中巧妙实现clickhouse分页,方便快捷,两个页面实现,亲测可用

    在Java项目中,分页是常见的数据查询需求,特别是在大数据量的场景下,如ClickHouse数据库的使用。PageHelper是一个非常流行的MyBatis插件,它提供了强大的分页功能,但有时我们可能出于某些原因不希望引入额外的...

    海量数据分页sql server经典

    该存储过程接收SQL查询语句、当前页码、每页记录数、排序依据等参数,并通过动态构建SQL语句来实现分页查询。 #### 总结 通过对上述几种分页方法的分析,我们可以看出,基于SQL查询的分页方法相较于传统的游标...

    三大数据库的分页语句

    另外,对于大数据量的表,使用`ROW_NUMBER()`函数(在Oracle和SQL Server中)或`RANK()`/`DENSE_RANK()`(在MySQL中)可能更为高效,尤其是在需要根据特定条件排序时。 在进行分页查询时,还应考虑性能优化,如避免...

    分页,自动分页,后台专用

    1. **分页基础概念**:分页是将大量数据分割成较小、可管理的部分,通常每个部分称为一页。用户可以逐页浏览,而不是一次性加载所有数据,这降低了内存需求,提高了页面加载速度,并使用户更容易找到所需信息。 2. ...

    非常优秀的Java分页代码

    分页的基本原理是将大量的数据集分割成较小的部分,每次只加载一部分数据到内存中,用户可以逐页浏览,而不需要一次性加载所有数据。在Java中,实现分页通常涉及两个主要参数:当前页数和每页显示的记录数。 1. **...

    在ASP.NET 2.0中操作数据之二十五:大数据量时提高分页的效率

    导言  如我们在之前的教程里讨论的那样,分页可以通过两种方法来实现:  1.默认分页– 你仅仅只用选中...但是它每次都读取所有的数据,这种方式在大数据量或者并发用户多的情况下就不合适.在这样的情况下,我们必须通

    Oracle 高效分页存储过程(修改)

    在Oracle中,我们可以使用ROWNUM伪列来实现简单的分页,但这种方法在处理大数据量时效率低下,因为它会先返回所有满足条件的记录,然后再筛选出指定范围内的行。 为了解决ROWNUM的性能问题,Oracle引入了ROW_NUMBER...

    sql 分页存储过程

    "sql分页存储过程"是指利用存储过程实现数据查询时的分页功能,这在大数据量的查询中尤为重要,因为直接一次性返回所有结果可能会消耗大量系统资源并导致响应时间过长。 分页查询是数据库中常用的一种技术,它允许...

    SQL2005 大数据量检索的分页

    综上所述,SQL Server 2005中的大数据量检索分页可以通过`ROW_NUMBER()`函数实现,同时注意性能优化和并发控制,以提供高效且稳定的查询服务。在实际应用中,应结合业务需求和数据规模灵活调整策略,确保系统的高效...

    肤浅的SQL分页代码,急需完善

    在SQL查询中,分页是实现数据库数据浏览的重要功能,特别是在大数据量的场景下,它可以帮助用户逐批加载数据,避免一次性加载所有记录导致的性能问题。标题“肤浅的SQL分页代码,急需完善”暗示了当前的实现可能存在...

    oracle存储过程通用分页

    分页是将大型数据集分成若干小块,每次只加载一部分数据到内存中,这样可以减少网络传输的数据量,提高页面加载速度,并减轻服务器的负担。在Oracle中,我们可以使用ROWNUM伪列来进行分页,但这种方法在某些情况下...

    Java分页Java分页Java分页

    - **数据量控制**: 分页可以有效减少一次性加载到内存中的数据量,避免内存溢出问题。 - **缓存策略**: 可以结合缓存技术如Redis,将分页结果存储在缓存中,减少对数据库的访问压力。 3. **Java分页库** - **...

    asp.net(c#)实现大文章分页测试

    - 数据库索引:确保用于排序和分页的字段有合适的索引,以提高查询性能。 - 输出缓存:对于静态的分页内容,可以使用ASP.NET的输出缓存机制,减少服务器计算压力。 - 分页策略:根据实际情况选择是否一次性加载...

Global site tag (gtag.js) - Google Analytics