热门标签 | HotTags
当前位置:  开发笔记 > 数据库 > 正文

查询性能“逆袭”—巧用“BETWEEN”

查询性能逆袭巧用BETWEEN一、问题的背景有若干个表(暂且认为4个表),这几个表的主要字段一致,即有若干个公共的字段,其中ID具有唯一性,并且四个表中唯一,类型为String.。如下面所示:table1(ID,Name,Type,CommonField1,CommonField12,Table1Ot

查询性能逆袭巧用BETWEEN 一、问题的背景 有若干个表(暂且认为4个表),这几个表的主要字段一致,即有若干个公共的字段,其中ID具有唯一性,并且四个表中唯一,类型为String.。如下面所示: table1(ID,Name,Type,CommonField1,CommonField12,Table1Ot

查询性能“逆袭”—巧用“BETWEEN”

一、问题的背景

有若干个表(暂且认为4个表),这几个表的主要字段一致,即有若干个公共的字段,其中ID具有唯一性,并且四个表中唯一,类型为String.。如下面所示:

table1(ID,Name,Type,CommonField1,CommonField12,……Table1OtherField1……)

table2(ID,Name,Type,CommonField1,CommonField12,……Table2OtherField1……)

table3(ID,Name,Type,CommonField1,CommonField12,……Table3OtherField1……)

table4(ID,Name,Type,CommonField1,CommonField12,……Table4OtherField1……)

至于这个表为什么设计成这样,是否达到基本范式?这个问题这里暂时不考虑,可以简单的认为这四个表存储了四类非常类似的数据。上级系统有这样的查询需求,暂且叫分页查询,类似一个Session的概念:

1、 需要查询的时候会发一个创建查询的消息,里面带了查询条件,并且说明了每次查询返回的数量。

2、 应答创建查询的消息中要返回符合查询结果的总数目,并且返回第一页数据。当然如果满足结果的数目小于每次查询的数据,直接将满足的结果返回。

3、 如果满足结果的总量大于每次查询的数量,即需要分页查询,那么,上级系统会发查询消息来查询第二页、第三页……依次类推,直至查完。

4、 查询完毕后,上级系统会发送一个删除查询的消息。

上面的查询条件是非常复杂的,没有使用类似SQL的语法解析,而是通过一个数据结构和查询文档描述。

具体例子说明:假如上级系统发一个创建查询的消息,假定总共有10万数据,每次查询为1000条,查询实现端收到该报文后,解析查询条件,查询得到有4999条满足查询条件的数据,那么第一次返回的报文中返回前1000条,并且注明满足条件的总数为4999。接着上级系统会发送查询消息,指定查询第二个1000条,依次查询,直到查到最后的999条,上级系统再发一个删除查询表示查询结束。对上级查询者而言,表的数量对其而言是透明的,默认就是这几个表中查询。查询示意图如下:

二、解决问题的思路

1、 缓存查询结果:根据查询条件,一次性将查询结果缓存,在内存中分页返回查询结果。最大的问题是如果满足结果数量级大的情况下很容易OOM。

2、 缓存查询符合条件的ID:根据查询条件,创建查询的时候先查询到所有符合条件的ID,将ID分页,每次查询请求来的时候用ID去查询本次需要的数据。构造SQL需要有技巧。

3、 缓存查询条件:每次来查询的时候根据查询条件来查询到所有数据,然后根据要求返回某一页。每次要重复解析查询条件,处理起来十分麻烦,也存在数据的不一致性。

实际实现中采用了第二种方案(方案二的问题在方案三中同样存在),处理起来简单又方便。但是问题又出现了,如果在一个查询“会话”中,创建查询的时候查询得到4999个ID,然后分5次返回,每次返回的数据中都需要根据1000个ID查询得到这1000行数据,那么我们很自然的会想到用”sellect * form XXXwhere in(…..)”由于SQL语句的长度限制,1000个ID就要查几十次,4999数据的话总共要查近百次,如果数据上几十万的话,查询次数更是吓人,查询时间将大部分花在不停的执行SQL查询上。那怎么来绕开这个弯子?

三、减少SQL查询次数的思路

先看个例子,假如数据库中只有这样是个ID的数据【1,2,3,4,5,6,7,8,9,10】,如果要查询ID为【2,3,4,7,8,10】,那么是否可以有这样两种思路来组织SQL查询条件

1、 where id in(2,3,4,7,8,10);

2、 where id between ‘2’ and ‘4’ orbetween ‘7’ and ‘8’ or between ‘10’ and ‘10’

上面的第二种用between方式构建查询条件,SQL语句基本上可以用一个完成?最坏的情况(也是SQL语句最长的情况)也就是需要查询的数据是ID【1,3,5,7,9】的情况。在实际数量巨大的情况下几乎不会出现这样“最糟糕的情况”,一般需要查询的数据是连续的,因此基本上任何查询都可以用一个between搞定。而如果用第一种方式构造查询条件,那么势必需要查询多次。

四、实际处理

以上面的例子为例,如果总数是10万条,符合条件的是4999条,那么可以这么做:

1、 将所有的10万个ID取出来缓存在内存并进行排序。

2、 将4999个查询结果ID缓存进行排序。

3、 每次查询1000(最后一次是999)数据时根据这1000ID和全部的10万个ID关系,通过某个算法构建between条件(这个算法不再详述),最终构造一个SQL查询条(注意只是一个SQL),这样一次查询就可以得到这1000条数据。

上面的缓存ID的方案是可行的,一般不会产生OOM。结果就是几百次查询优化成了一个查询,查询性能直接逆袭!


推荐阅读
  • 58同城的Elasticsearch应用与平台构建实践
    本文由58同城高级架构师于伯伟分享,由陈树昌编辑整理,内容源自DataFunTalk。文章探讨了Elasticsearch作为分布式搜索和分析引擎的应用,特别是在58同城的实施案例,包括集群优化、典型应用实例及自动化平台建设等方面。 ... [详细]
  • 本文提供了一套实用的方法论,旨在帮助开发者构建能够应对高并发请求且易于扩展的Web服务。内容涵盖了服务器架构、数据库管理、缓存策略以及异步处理等多个方面。 ... [详细]
  • 随着iPhone 11系列的发布,苹果公司引入了先进的夜间模式,显著提升了夜间摄影的质量,解决了之前版本在低光环境下拍摄效果不佳的问题。 ... [详细]
  • 不同城市的Python工程师薪资对比与工程机械操作员的薪资分析
    本文探讨了中国各主要城市Python工程师的薪资水平,并对工程机械行业中多种机械设备操作员的薪资进行了详细分析。通过对比不同设备的操作难度和技术要求,为有意进入该领域的求职者提供了参考。 ... [详细]
  • 深入理解Kafka架构
    本文将详细介绍Kafka的内部工作机制,包括其工作流程、文件存储机制、生产者与消费者的具体实现,以及如何通过高效读写技术和Zookeeper支持来确保系统的高性能和稳定性。 ... [详细]
  • 在Ubuntu 16.04中使用Anaconda安装TensorFlow
    本文详细介绍了如何在Ubuntu 16.04系统上通过Anaconda环境管理工具安装TensorFlow。首先,需要下载并安装Anaconda,然后配置环境变量以确保系统能够识别Anaconda命令。接着,创建一个特定的Python环境用于安装TensorFlow,并通过指定的镜像源加速安装过程。最后,通过一个简单的线性回归示例验证TensorFlow的安装是否成功。 ... [详细]
  • 探索微信影响力排名的秘密:解读并计算WCI指数
    在日常浏览微信时,我们经常能见到各类新媒体影响力排行榜。其中,最后一列的WCI指标常引起人们的好奇。本文将深入解析WCI的含义及其计算方法,并通过Python代码实例展示如何计算WCI V14.2。 ... [详细]
  • 深入探讨机器学习中的查准率、查全率及F1分数
    本文详细解析了机器学习领域中常用的性能评估指标——查准率、查全率及其综合评价指标F1分数,通过具体案例分析这些指标在实际应用中的重要性和差异。 ... [详细]
  • 对称与非对称加密技术的比较及应用
    本文探讨了对称加密与非对称加密的主要区别,重点分析了非对称加密中的公钥体系及其在解决密钥分发问题上的优势。对称加密依赖单一密钥进行加密解密,而非对称加密则采用一对公私钥来完成安全通信。 ... [详细]
  • 聚焦法是一种采用穷尽搜索策略的Filter型特征选择方法,其核心在于寻找能有效区分不同样本的最小特征集合。此方法的评估标准主要依赖于一致性测量。 ... [详细]
  • Serato 推出全新 Stems 功能,DJ 软件迎来重大升级
    Serato 最近为其 DJ 软件推出了全新的 Stems 功能,使得用户能够轻松地将音乐中的不同部分如人声、旋律、贝斯和节奏进行分离,为音乐创作和现场表演提供了更多可能性。 ... [详细]
  • 本文详细介绍了WebRTC提供的音频处理引擎,包括自动增益控制(AGC)、噪声抑制(ANS)、移动设备声学回声消除(AEC)及静音检测(VAD)等核心算法,并提供了完整的C语言实现代码。 ... [详细]
  • 最近在深入学习《数据结构与算法–JavaScript描述》一书,尝试通过npmjs.org寻找合适的库作为参考,但未能找到完全符合需求的资源。因此,决定自行实现一个字典数据结构,以便日后能够直接应用。 ... [详细]
  • 车载T-BOX智能网联终端的设计与实现
    本文介绍了一款基于瑞萨RH850微控制器、TICC2640R2F蓝牙微控制器和高通MDM9628处理器的T-BOX车载终端的设计。该终端通过集成CAN总线、GPS定位、数据加密、蓝牙通信和LTE无线数据传输技术,实现了车辆信息的高效采集与云端通信,支持远程车辆控制和诊断等功能。 ... [详细]
  • 近期尝试重构 GDI 并自定义图像处理函数时,发现自定义函数的图像复制性能显著低于 Windows 原生 GDI 函数。通过研究了解到,系统可能利用了 GPU 加速来提升这些函数的效率。 ... [详细]
author-avatar
我心永恒2602922374_902
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有