内置的数据无法实现高性能

简介:

_

这里说的“内”, 是指数据库之内。

当数据量变大时,我们常常会感到数据库的性能下降明显,但是,无论怎样优化 SQL(存储过程)都仍然与根据数据量和运算复杂度计算出来的理论性能相差甚远。这主要由如下几方面原因造成:

1. SQL 限制与优化困难

我们已经多次说过,由于关系代数和 SQL 语法的限制,有许多高效的算法无法实施,比如前面说过的遍历复用技术,以及去年谈过的 JOIN 优化方法。使用 SQL 实现这类运算时,只能采用复杂度更高的方法,冗余的数据访问量和计算量非常大,而且也很难利用多 CPU 进行并行计算。

SQL 不提倡分步计算,经常一条语句写出几百行、嵌套很多层。不分步的长语句很难利用某个子句的计算结果,常常带来不必要的重复计算。而且过于复杂的也会给数据库优化引擎造成负担,优化引擎不能很好地理解运算逻辑而设计出最优的执行路径。我们常常发现一条语句的几个子部分执行都很快,结果集也不大,但合起来写到一句 SQL 中就会很慢。

2. 存储过程性能差

对于复杂的多步骤计算,我们常常要编写存储过程才能实现。而和 SQL 相比,存储过程的取数遍历过程要慢得多。同一个表的数据,使用存储过程先 FETCH 出来再做聚合,要比直接用 SQL 聚合的性能慢出几倍到十几倍,本来这两者的运算性能应当是差不多的(计算复杂度与数据访问量都一样)。有些针对明细数据的复杂处理只能把数据一条条取出才能实现时,这个性能就没办法得到保证了。

在存储过程中,为了利用前面计算出来的中间结果,只要涉及集合性数据一般都要使用临时表。而建表写数的动作也是非常慢的,数据库有太多约束性要求,而且常常需要把临时表落地到外存。

3. 直接外部计算不现实

如果我们不采用 SQL,而将数据读出后在库外计算,是否可以提高性能呢?

大多数情况仍然不可以。一方面原因是数据库 IO 性能大都很差,从数据库中取数,要比从文件系统中读数的性能差出一个数据量,经常发生取数时间远远超过计算时间的现象。

而且,有些高效算法会要求有特殊的存储格式,比如需要事先将数据排序存储,从而可以采用分段定位查找或实现有序归并算法,而基于无序集合的 SQL 在理论上就无法支持,必须先排序才能保证取出数据的有序性,结果排序时间会超过计算本身。再比如行存或列存的选择,一般数据库只会采用一种(支持 OLTP 用行存且不压缩,面向 OLAP 用列存并压缩),但使用行存还是列存需要由计算目标决定,在遍历式计算采用列存较为合适,而使用索引定位查找时则更适合用行存。有时为了性能还可能把同一份数据存储冗余的多份以面向不同用途,而在数据库中很难有这么灵活的处理方式。

解决办法,就是数据外置,具体说就是把数据搬出数据库。使用合理的存储方案再配以适用的算法,对于许多几百上千行的存储过程,经过这样的改造后,性能常常都有几倍的增长。

当然,这又会带来新的问题。主要有三个方面:一是可管理性,在数据库中有统一的数据视图和约束性检查,而外部文件系统则没有这些东西;二是安全性,数据库是个封闭体系,获取数据的接口很单一,总有帐号认证的过程,而文件系统也没有这些东西;三是数据更新能力,数据在不断地变化中,数据库有完整的数据更新功能,文件系统这方面却很弱,一般只能做追加,还很难保证追加过程中的一致性(中途出错时恢复)。

目前阶段这个事还是需要权衡,获得了数据库的方便性就得不到高性能,要数据外置的高性能就要牺牲方便性。不过,随着技术的进步,在文件系统上加强可管理性、安全性以及可更新能力又不牺牲或很少牺牲其性能,还是有可能做到的,数据库的封闭性总要被打破。

作者:279400248
链接:http://c.raqsoft.com.cn/article/1535513386417
来源:乾学院
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

相关文章
|
1月前
|
存储 缓存 NoSQL
Redis数据存储:高效、灵活、实时
Redis数据存储:高效、灵活、实时
|
4月前
|
存储 对象存储 块存储
高性能数据存储有哪些方式
高性能数据存储有哪些方式
55 0
|
5月前
|
存储 缓存 算法
分布式数据库架构:高可用、高性能的数据存储
分布式数据库架构:高可用、高性能的数据存储
518 0
|
10月前
|
存储 缓存 负载均衡
高性能是什么?其本质是什么东东?
高性能是什么?其本质是什么东东?
126 0
|
11月前
|
存储 移动开发 负载均衡
大厂如何打造可扩展的高并发系统?
高可扩展性是个设计指标:表示可通过加机器线性提高系统处理能力,承担更高流量和并发。 架构设计之初,为什么不预先考虑好使用多少台机器,支持现有并发呢?因为峰值流量不可控。
66 0
|
存储 缓存 算法
提高存储系统性能的技术
提高存储系统性能的技术
127 0
|
算法 NoSQL 数据库
如何设计一款“高可用高性能”的发号器?
在分布式场景中,很多地方需要生成全局唯一的id,如数据库分库分表后需要用唯一id代替单机版本的自增id。发号器的基本要求是 全局唯一,无论如何都不能重复 某些场景下还要求单调递增,如排序需求等。
337 0
如何设计一款“高可用高性能”的发号器?
|
弹性计算 编解码 负载均衡
如何构建一套高性能、高可用性、低成本的视频处理系统?
基于函数计算和 Serverless 工作流的弹性高可用视频处理架构,充分体现了云原生时代 Serverless 化思想,以事件驱动的形式触发函数执行,真实计算资源真正意义上的按需使用。对于使用而言,这套方案在保证业务灵活度的同时,可以显著降低维护成本与资源成本,并大幅度的缩短项目交付时间。
4838 1
如何构建一套高性能、高可用性、低成本的视频处理系统?
|
Web App开发 算法 前端开发
当我们谈高性能时,我们谈些什么?
网站越快,用户忠诚度更高; 网站越快,用户转化率越高。 简言之,速度是关键。 ——《Web 性能权威指南》 显然,高性能意味着“快”。但对快的定义,在不同的系统中,标准是不一样的。为了获得快的体验,通常我们需要平衡成本和收益等方面制定优化方法。
1793 0