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

当数据量变大时,我们常常会感到数据库的性能下降明显,但是,无论怎样优化 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. join 高性能_内置的数据无法实现高性能

    内置的数据无法实现高性能 这里说的"内", 是指数据库之内. 当数据量变大时,我们常常会感到数据库的性能下降明显,但是,无论怎样优化 SQL(存储过程)都仍然与根据数据量和运算复杂 ...

  2. 数据蒋堂 | 内置的数据无法实现高性能

    作者:蒋步星 来源:数据蒋堂 本文共1400字,建议阅读7分钟. 获得了数据库的方便性就得不到高性能,要数据外置的高性能就要牺牲方便性. 这里说的"内", 是指数据库之内. 当数据 ...

  3. python内置作用域_python内置金融数据Python 五点搞定作用域

    1.块级作用域 想想此时运行下面的程序会有输出吗?执行会成功吗?#块级作用域 if 1 == 1: name = "lzl" print(name) for i in range( ...

  4. java分页插件PageHelper的内置list数据操作失败

    问题描述: java分页插件PageHelper的内置list数据在hanlder处理器中获取失败,但是测试确通过了,如下图 但是测试代码成功 @ContextConfiguration(locati ...

  5. java使用poi在word中生成柱状图、折线图、饼图、柱状图+折线图组合图、动态表格、文本替换、图片替换、更新内置Excel数据、更新插入的文本框内容、合并表格单元格;

    本文参考地址:https://blog.csdn.net/wangxiaoyingWXY/article/details/95377533 在参考文章的基础上,增加了扩展.感谢被参考的妹子.另外该博客 ...

  6. matlab获取手机传感器,分享采集Android内置传感器数据到MATLAB的方法

    本方法能够实现安卓手机内置的加速度传感器.陀螺仪.磁场数据.角速度传感器及GPS数据采集到MATLAB. 1.硬件准备:安卓手机,电脑,且在同一局域网中: 2.软件准备:安卓手机安装MATLABmob ...

  7. 读android内置存储芯片数据,WEIPOS开店宝安卓收银机内置存储DIY硬改扩容成功,分享一下心得和体会...

    认识众多玩家高手/拆客/DIYer,查阅更多资源,一起学习技术知识 您需要 登录 才可以下载或查看,没有帐号?立即注册 x 帖子比较长,请耐心观看哈! 一.前言 之前在坛子里发过贴,向坛子里的大佬们讨 ...

  8. 深入浅出CChart 每日一课——快乐高四第九课 于无声处,CChart内置功能介绍之数据存取篇...

    笨笨长期以来一直使用Origin软件画图和处理数据,但Origin软件没有编程语言的接口.笨笨开发CChart的一个潜在的目标.是想实现Origin软件的功能.当然这是一个不可能达到的目标.Origi ...

  9. uniapp内置组件

    目录 3.1.视图容器 view scroll-view swiper match-media 3.2.表单组件 form input App平台iOS端软键盘上方横条去除方案 关于软键盘弹出的逻辑说 ...

最新文章

  1. Ubuntu 14.04安装mysql
  2. 【PC工具】图片批量添加水印工具,绿色免安装工具软件
  3. 产品经理必备知识之网页设计系列(三)-移动端适配无障碍设计及测试
  4. Maven -- group、artifact、package
  5. 【深度学习】PyTorch深度学习技术生态
  6. netty web 容器_Netty 实战:如何编写一个麻小俱全的 web 框架
  7. python更新包列表出错_解决pycharm无法获取安装包文件列表
  8. keras保存模型_TF2 8.模型保存与加载
  9. PHP实现一个轻量级容器
  10. Docker基础知识:Containers,Namespace,CGroups
  11. vuex的计算属性_vue中vuex的五个属性和基本用法
  12. 让OSX terminal更出彩
  13. IRQL的理解和认识
  14. Windows系统中禁止某应用程序联网操作方法
  15. 关于光的波粒二象性的解释--答复年少时的疑惑
  16. 2048php,Phaser实现2048
  17. label 详细用法
  18. html大一期末考试,2017年大学英语大一期末考试试题及答案
  19. python实现电商平台秒杀商品脚本程序
  20. 如何安装Mac 下的markman破解版

热门文章

  1. jedis操作set_redis命令行操作set集合和java方式操作set集合
  2. jsp mysql驱动程序_JSP通过JDBC驱动MySQL数据库方法
  3. python中if __name__ == '__main__'功能的解析
  4. 【赠书】图神经网络优质书籍,送你3本进行学习
  5. 【NLP】 NLP专栏栏主自述,说不出口的话就交给AI说吧
  6. 【图像分割模型】实例分割模型—DeepMask
  7. 揭秘7大AI学习板块,这个星球推荐你拥有
  8. WinForm界面开发之布局控件WeifenLuo.WinFormsUI.Docking的使用
  9. 找不到atlapp.h的解決方法
  10. 获得Google搜索字符串中的关键字