热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

oracle分页查询优化_Mongodb分页查询优化上

【背景】最近遇到mongo集群性能问题,主要体现在查询性能或者聚合性能慢(查询类似关系型数据库中select*fromxxwhereaxx,另外聚合类似groupbycount、s

【背景】

       最近遇到mongo集群性能问题,主要体现在查询性能或者聚合性能慢(查询类似关系型数据库中select * from xx where a='xx',另外聚合类似group by+count、sum),nosql与关系型数据库存在很多类似,比如分页查询语句是比较常见问题,分页优化在数据库优化原理类似.常见分页场景需求(本次主要基于这2种场景进行优化介绍)

    1、取top N这种小结果集,想办法利用索引有序特性尽快返回结果集.

db.collection.find({query}).sort({name:1}).limit(50)

    2、分页翻页,尤其是结果集特别多越往后翻页越慢db.collection.find({query}).sort({name:1}).skip(N).limit(50),这里N越大,性能会越低.

【分页top N案例以及优化思路】

       1、具体SQL逻辑:根据网点查询当天的签收明细并返回第一页2000条,所有sql都是查询当天签收,当天从00:00:00-23:59:59,查询时间越接近23:59:59,满足结果集的数据越多,直到数据没有变化.后面还有翻页的功能,暂时先不讨论.其中sort是根据单号来,所有单号都唯一的.signStatus只有0,1.

  db.test.find({org:"10000",signT:{$gte:new Date(1590940800000), $lte: new Date(1591027199999) }, signStatus: { $in: [ 0, 1 ] } }).sort({no:1}).limit(2000);

        2、慢日志中分析不同不同索引对应效率

通过mtools分析慢日志,平均执行时间300ms.

c70e16517495054186ca720dc4fd1ecd.png

        分析一个慢日志情况:

        排序顺序与索引顺序一致则无需排序,执行时间是1084ms:索引【org_1_no_1_signT_1】

        排序顺序与索引顺序不一致则需排序,执行时间是156ms:  索引【org_1_signT_1】

    【org_1_no_1_signT_1】索引执行效率:

    备注:返回6000,因为存在3个分片,需要mongos进一步过滤

     "executionStats": {

         "nReturned": 6000,

         "executionTimeMillis": 1084,

         "totalKeysExamined": 168130,

         "totalDocsExamined": 6000

 【org_1_signT_1】索引执行效率

     "executionStats": {

         "nReturned": 6000,

         "executionTimeMillis": 156,

         "totalKeysExamined": 43744,

         "totalDocsExamined": 43744

       总结:1、排序与回表效率问题;--针对当前小结果集下,ER索引效率要明显高于ESR索引效率.

                 第一个索引满足ESR理论,通过索引没有返回多余的行数,每个节点2000行,但是从16万索引key中过滤满足条件6000,解决排序问题,无排序回表少,索引是检索效率低且执行时间长

                第二个索引不满足ESR理论,只能满足ER理论,索引key与回表结果集一致,回表过滤到37744条.有排序回表多,索引效率高.执行时间短.   

             2、如果结果集呈现N倍数据级增长,比如百万级别,那么ER索引效率肯定低于ESR索引效率,虽然说ESR理论下最佳,但本次SQL写法ESR效率不高.

       3、了解业务需求以及设计原因

    db.test.find({org:"10000",signT:{$gte:new Date(1590940800000), $lte: new Date(1591027199999) }, signStatus: { $in: [ 0, 1 ] } }).sort({no:1}).limit(2000);

          signT时间基本上都是一个时间点,存在少量不一样时间,所以说排序字段不能signT.所以采用no单号,后续沟通集合中存在一个staDate字段,同一天日期完全一致,后续将代码中signT使用staDate来替代,并修改索引为ES索引,完美解决排序与回表问题.

          创建索引:mongodb 4.2版本开始,background:1可以不用加,类似oracle或者mysql online ddl,只是在创建索引与结束加锁.4.2版本之前,后台创建索引比较慢,前台创建是db级别排他锁,导致整个db无法访问.谨慎操作。

          db.test.createIndex({org:1,staDate:1,no:1},{background:1})

      4、最终修业务SQL如下

     db.test.find({org:"10000",staDate: new Date(1591027199999) }, signStatus: { $in: [ 0, 1 ] } }).sort({no:1}).limit(2000);

   【org_1_no:1_staDate_1】索引执行效率

"executionStats" : {

"executionSuccess" : true,

"nReturned" : 6000,

"executionTimeMillis" : 10,

"totalKeysExamined" : 6000,

"totalDocsExamined" : 6000,

【分页top N优化总结】

     1、性能提升 

       通过修改业务SQL逻辑,top 2000执行基本几十毫秒,相比之前最低都要100ms,最大要几秒,性能提升几倍到几十倍,如果数据量提升几个数理级别,提升至少100倍.

     2、不管ESR最佳实践还是ES或者SR等相关索引规则,都是结合实际SQL以及结果集大小来具体问题具体分析,本案例中没有修改业务代码前ER比ESR效果好,即使ER有排序,这些都是建立结果集小的情况下,如果结果集很大,不管ESR还是ER都存在缺点,集合或者索引变成热点问题。




推荐阅读
  • 本文介绍了一个在线急等问题解决方法,即如何统计数据库中某个字段下的所有数据,并将结果显示在文本框里。作者提到了自己是一个菜鸟,希望能够得到帮助。作者使用的是ACCESS数据库,并且给出了一个例子,希望得到的结果是560。作者还提到自己已经尝试了使用"select sum(字段2) from 表名"的语句,得到的结果是650,但不知道如何得到560。希望能够得到解决方案。 ... [详细]
  • 本文介绍了Oracle数据库中tnsnames.ora文件的作用和配置方法。tnsnames.ora文件在数据库启动过程中会被读取,用于解析LOCAL_LISTENER,并且与侦听无关。文章还提供了配置LOCAL_LISTENER和1522端口的示例,并展示了listener.ora文件的内容。 ... [详细]
  • 本文讨论了在数据库打开和关闭状态下,重新命名或移动数据文件和日志文件的情况。针对性能和维护原因,需要将数据库文件移动到不同的磁盘上或重新分配到新的磁盘上的情况,以及在操作系统级别移动或重命名数据文件但未在数据库层进行重命名导致报错的情况。通过三个方面进行讨论。 ... [详细]
  • 基于PgpoolII的PostgreSQL集群安装与配置教程
    本文介绍了基于PgpoolII的PostgreSQL集群的安装与配置教程。Pgpool-II是一个位于PostgreSQL服务器和PostgreSQL数据库客户端之间的中间件,提供了连接池、复制、负载均衡、缓存、看门狗、限制链接等功能,可以用于搭建高可用的PostgreSQL集群。文章详细介绍了通过yum安装Pgpool-II的步骤,并提供了相关的官方参考地址。 ... [详细]
  • 一、Hadoop来历Hadoop的思想来源于Google在做搜索引擎的时候出现一个很大的问题就是这么多网页我如何才能以最快的速度来搜索到,由于这个问题Google发明 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 本文介绍了数据库的存储结构及其重要性,强调了关系数据库范例中将逻辑存储与物理存储分开的必要性。通过逻辑结构和物理结构的分离,可以实现对物理存储的重新组织和数据库的迁移,而应用程序不会察觉到任何更改。文章还展示了Oracle数据库的逻辑结构和物理结构,并介绍了表空间的概念和作用。 ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • Oracle Database 10g许可授予信息及高级功能详解
    本文介绍了Oracle Database 10g许可授予信息及其中的高级功能,包括数据库优化数据包、SQL访问指导、SQL优化指导、SQL优化集和重组对象。同时提供了详细说明,指导用户在Oracle Database 10g中如何使用这些功能。 ... [详细]
  • 本文详细介绍了MysqlDump和mysqldump进行全库备份的相关知识,包括备份命令的使用方法、my.cnf配置文件的设置、binlog日志的位置指定、增量恢复的方式以及适用于innodb引擎和myisam引擎的备份方法。对于需要进行数据库备份的用户来说,本文提供了一些有价值的参考内容。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 高质量SQL书写的30条建议
    本文提供了30条关于优化SQL的建议,包括避免使用select *,使用具体字段,以及使用limit 1等。这些建议是基于实际开发经验总结出来的,旨在帮助读者优化SQL查询。 ... [详细]
  • ALTERTABLE通过更改、添加、除去列和约束,或者通过启用或禁用约束和触发器来更改表的定义。语法ALTERTABLEtable{[ALTERCOLUMNcolu ... [详细]
  • Linux如何安装Mongodb的详细步骤和注意事项
    本文介绍了Linux如何安装Mongodb的详细步骤和注意事项,同时介绍了Mongodb的特点和优势。Mongodb是一个开源的数据库,适用于各种规模的企业和各类应用程序。它具有灵活的数据模式和高性能的数据读写操作,能够提高企业的敏捷性和可扩展性。文章还提供了Mongodb的下载安装包地址。 ... [详细]
author-avatar
LeoWang
帅气鄙人的PHP程序员
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有