当前位置: 首页 > 科技观察

SQL(和存储过程)运行太慢怎么办?

时间:2023-03-20 15:33:46 科技观察

SQL作为最常用的数据处理语言,广泛应用于查询、批量运行等场景。当数据量很大时,使用SQL(和存储过程)往往运行很慢,这就需要对SQL进行优化。优化SQL有一些具体的套路。通常需要通过检查执行计划来定位SQL慢的原因,然后重写优化SQL。比如对于连续的数值判断,可以用between代替in,select语句指定字段名,用unionall代替union,重写existsasjoin等。当然也有一些工程优化的方法,比如比如索引,使用临时表/汇总表等。优化的方法有很多,相信各位DBA都不陌生。但遗憾的是,还是有相当一部分情况,无论怎么优化都无法跑得更快。在这里做SQL性能优化,真是让人大跌眼镜。我介绍了一些并做了相应的技术分析。SQL由于其理论基础关系代数的局限性,缺乏对离散集和有序集等特性的支持,使得SQL很难表达某些高性能算法,甚至根本无法写出来,所以我们只能使用比较笨的低性能算法。看着硬件资源白白浪费。对于SPL这种简单快速的数据库语言中SQL的理论基础存在的缺陷,有一个流行的解释。也就是说,SQL的慢是理论上的。这种问题只能通过工程层面的数据库优化来部分改善(确实很多商业数据库可以自动识别某些SQL并转化为高性能算法),但不能从根本上改善。高效解决问题(当情况复杂时,数据库优化引擎会“晕”,只能按照SQL的编写逻辑作为低性能算法执行)。当然,理论上的缺陷并不能通过更换数据库来解决。只要仍然使用SQL,即使使用分布式数据库或内存数据库也是如此。当然,在消耗更多昂贵的资源后,它仍然可以有一定的性能。但与硬件应能达到的性能还有很大差距。我还可以做些什么?那你就不能再用SQL了!您不能再使用关系数据库。它是做什么用的?SQL都描述不了这些高性能算法,Java和C++行得通吗?没问题!从理论上讲,Java和C++中的任何算法都可以实现,而且因为它可以控制计算机的底层动作,所以这类代码通常可以以非常好的速度运行(只要程序员的能力不是太差)。不过大家也不要太激动,虽然可以写,但是因为这些开发语言太原生了,并??没有提供任何用于数据处理的高性能计算库。如果要实现这些算法,就必须从头开始实现,这可能会很累。死。以哈希关联为例,Java实现至少需要几百行代码,不仅要设计合适的哈希函数,还要解决可能存在的哈希冲突。这一套涉及的工作量不小;在计算机中进行多线程编程并不容易,但并行计算是提高计算性能的有效手段。同样,涉及到结构化数据计算的算法还有很多,自己做这些的复杂度可想而知。如果一个计算的实现过于复杂,其开发成本远远超过性能优化本身,那么优化就没有意义了。Python也面临着类似的问题。虽然在结构化数据计算库方面比Java丰富很多,但没有提供必要的高性能算法库和存储方案。例如,它不提供大数据服务的游标类型和相关操作,也不提供有效的并行机制。想要实现那些高性能的算法,只能自己开发。然而,作为一种解释型执行语言,Python本身并不高效,在此基础上开发的算法往往不能满足高性能要求。同样,Scala也缺乏足够的高性能计算库,自己写的算法也相当复杂。对于不熟悉这些算法的程序员来说,从头实现的代码运行效率往往还不如经过苦练的商业数据库SQL。速度。那么我们只能忍受SQL的慢吗?您也可以使用SPL!SPL和高性能开源SPL(StructuredProcessLanguage),一种用于结构化数据处理的编程语言。使用SPL可以使原本在SQL中很慢的计算变得更快。为什么SPL能跑得快?有没有改变硬件性能的黑科技?这不是真的。软件不能改变硬件的计算性能,SPL也不能。简单的说,SPL就是快,就像上面说的,要使用更高性能的算法。SPL提供了大量的基础高性能算法类库。基于这些算法库实现的代码可以有效的减少计算量,我们结合这些算法进行计算。每一次计算都快,整体就会快很多,从而达到提高计算性能的目的。这些由SPL设计的高性能算法,如遍历复用、有序合并、外键预关联、标签维数、并行计算等,都被封装了。其中许多算法是SPL独有的,并且是业内首次出现。基于这些封装好的算法库,编写程序会非常方便,可以直接使用,无需从头开发。不仅性能高,而且开发速度也快。从这个角度看,跑得快和写得简单其实是一回事,就是能高效地写出高性能的算法。相比之下,由于Java、C++、Python、Scala中缺少这些算法库,很难实现高性能。SPL使用与SQL不同的概念来看待同一个计算任务,进而可以使用不同(更低)复杂度的计算方式。在实战中,SPL目前已经做了很多性能优化案例,从几倍到几十倍,极端情况下甚至上千倍。一个数量级的加速基本上是常态。例如,优化保险公司车险保单批量运行的案例(开源SPL将保险公司运行批次从2小时优化到17分钟),使用SPL将计算时间从2小时缩短到17分钟,代码量减少了2/3。这里采用了SPL独有的遍历复用技术,可以实现大数据一次遍历过程中的多次运算,有效减少外存访问量。本案例涉及对一张大表的三个关联和汇总操作。使用SQL需要遍历大表3次,而使用SPL只需要遍历一次,并且在关联操作中使用了不同的方法,因此获得了巨大的性能。推动。还有,在开源SPL将银行手机账户查询预关联变为实时关联的案例中,利用SPL将只能预关联的手机账户查询变为实时关联,同时服务器数量从6台减少到1台。这里充分利用了SPL的有序存储机制,可以有效减少一次读取整个账户数据时的硬盘时间(物理存储是连续的),然后利用外键实时关联技术区分维表和事实表使用单机完成实时关联查询,性能明显提升,对硬件的要求也降低很多。进一步讨论说到这里,您可能会想,是否可以通过学习SPL语法来更快地运行计算?没那么简单!关于算法,使用SPL来获得更高的性能并不是因为SPL语法。SPL语法虽然有一些特点,但并不是跑得快的根本原因。关键是掌握和使用高性能算法。实现性能优化有两个步骤:第一步是设计一个低复杂度的计算方案,第二步是以足够低的成本实现它。比较关键的是第一步,需要有一定经验和知识储备(即掌握和使用高性能算法)的程序员来完成,第二步是使用SPL来完成。换句话说,SPL不负责设计问题的解决方案,而只负责使解决方案更易于实施。SPL的语法很简单,比Java简单多了,两个小时基本就能学会,两三周就能更熟练。但是算法并没有那么简单,需要认真学习,反复练习才能掌握。反之,只要掌握了算法,使用什么语法是比较次要的问题(当然,像SQL这种太粗的语言还是不行的)。这就好比给病人看病,找出病理原因后,就可以分析药物是什么成分起作用了。不管是直接买现成的药(使用封装的SPL),还是上山采药(使用Java/C++硬写),都可以治病,只是麻烦程度和支付成本不同.因为在实践中很少用到,所以很多应用程序员在工作几年后就忘记了大学里学过的数据结构和算法课程。如果不了解这些基本的算法知识,就无法设计出高性能的算法。计划。为此,SPL专门设置了高性能专题,不仅涵盖高性能算法和优化技术,还有性能优化课程和性能书籍,授人以渔。高性能计算专题http://c.raqsoft.com.cn/article/1647044897121性能优化书籍http://c.raqsoft.com.cn/article/1613911172557性能优化课程http://www.raqsoft.com.cn/wx/course-performance-optimizing.html存储和算法密切相关。高性能计算的另一个关键点是数据存储。高性能计算离不开合理的数据存储方式。当使用SPL实现高性能计算时,已经不能基于数据库来做,需要将数据搬出数据库重新组织。为什么?慢数据计算任务可以分为两类:计算密集型和数据密集型。简单的计算密集型任务涉及的数据量小,但计算量大。计算量大并不是数据量大造成的。这样就不需要改变存储方式了。只要实现一个好的计算方法,就可以大大提高性能。也就是说可以在原有的存储方式(如数据库)上继续使用SPL来优化性能。数据密集型任务也涉及大量的计算,但计算量大主要是数据量大造成的。如果此时不改变存储方式,即使可以优化计算时间,读取数据的时间也很可能会很长。为0,整体运行时间无法有效优化。不幸的是,我们面临的大多数慢速计算场景都是数据密集型计算。如果数据还存在于数据库中,而数据库访问接口(如JDBC)通常很慢,读取数据的时间会很长(IO效率很低),往往远远超过后续的时间SPL计算,这也是不可能达到优化效果的。此外,SPL中的不少算法也对存储组织有要求。例如,单边堆算法需要有序的存储方式,而传统的关系型数据库不能满足这个前提,这些算法就无法实现。为了解决这个问题,SPL提供了自己的存储机制,直接使用文件系统将数据库中的数据导出到特定格式的文件中,这样不仅可以获得更高的IO访问效率和文件系统灵活的管理能力,还可以充分利用自身格式的列存、排序、压缩、并行切分等数据存储优势,从而有效发挥高性能算法的效能。使用文件存储数据还可以有效减少数据存储的时间,进一步提高计算性能。在一些计算场景中,不仅需要从数据源中读取,还需要将计算结果存储到数据库中,以供后续计算使用。比如ETL就是典型的读写并发计算。也有一些大数据计算或者复杂计算需要临时存储中间结果,需要在后续计算中复用的情况。我们知道写数据库是一个很慢的动作,伴随写的计算场景性能自然就低。这时候就可以把需要存入数据库的数据存入文件(虽然这是工程上的优势,但还是可以实现读写性能一个数量级的提升),然后使用文件SPL的计算能力直接计算,从而达到高性能。关于T+0,如果所有的数据都搬出数据库,是不是就无法完成实时的数据计算了?毕竟,数据总是在产生。没问题。对于全T+0的实时查询,SPL提供了多源混合计算的能力来满足这种场景。冷数据量大,不会变化。使用SPL的高性能文件存储,获得更高的计算性能;热点数据量仍然存储在原始数据源中,SPL直接读取计算(支持多样化数据源)。热点数据量不大,直接基于生产数据源查询不会对其造成太大影响,访问时间也不会太长。通过混合冷热数据,可以获得全量数据的T+0实时查询。我们只需要定期将冷数据固化到SPL的高性能存储中,原始数据源只需要保留少量新产生的热数据。整体结构如下:如何开始从前面的分析可以知道,要完成性能优化任务,必须熟悉高性能算法和存储机制。但是,从上面的课本中我们也可以看出,这些内容很多,想要全部掌握也不是一件容易的事。事物。尤其是很多程序员习惯了SQL的思维方式,很难走出这个窠臼。面对一个性能优化的任务,即使有开源SPL这样的利器,往往也有些难以下手。例如,当一个高手想要跑得更快时,他会习惯于寻找缰绳和鞭子,但他会对第一次看到的汽车上的方向盘和油门感到困惑。为此,SPL团队也提供相应的咨询服务:您可以带着您遇到的性能问题与我们共同探讨并设计优化方案,必要时也可以进行POC。我们通常会关心这样一些必要的问题信息:业务场景、痛点、当前计算的数据量和并发量、响应时间。如果能同时提供SQL脚本、表结构、测试数据就更好了。相信我们,绝不会错过!经历过一两个案例,程序员就会熟悉SPL的思维方式(理解方向盘和油门),以后自己做性能优化也不成问题。在武道的世界里,速度是唯一不可战胜的,但只有掌握了速度的本质和方法,才能立于不败之地。你不同意吗?