内置的数据无法实现高性能
这里说的“内”, 是指数据库之内。
当数据量变大时,我们常常会感到数据库的性能下降明显,但是,无论怎样优化 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
来源:乾学院
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
内置的数据无法实现高性能相关推荐
- join 高性能_内置的数据无法实现高性能
内置的数据无法实现高性能 这里说的"内", 是指数据库之内. 当数据量变大时,我们常常会感到数据库的性能下降明显,但是,无论怎样优化 SQL(存储过程)都仍然与根据数据量和运算复杂 ...
- 数据蒋堂 | 内置的数据无法实现高性能
作者:蒋步星 来源:数据蒋堂 本文共1400字,建议阅读7分钟. 获得了数据库的方便性就得不到高性能,要数据外置的高性能就要牺牲方便性. 这里说的"内", 是指数据库之内. 当数据 ...
- python内置作用域_python内置金融数据Python 五点搞定作用域
1.块级作用域 想想此时运行下面的程序会有输出吗?执行会成功吗?#块级作用域 if 1 == 1: name = "lzl" print(name) for i in range( ...
- java分页插件PageHelper的内置list数据操作失败
问题描述: java分页插件PageHelper的内置list数据在hanlder处理器中获取失败,但是测试确通过了,如下图 但是测试代码成功 @ContextConfiguration(locati ...
- java使用poi在word中生成柱状图、折线图、饼图、柱状图+折线图组合图、动态表格、文本替换、图片替换、更新内置Excel数据、更新插入的文本框内容、合并表格单元格;
本文参考地址:https://blog.csdn.net/wangxiaoyingWXY/article/details/95377533 在参考文章的基础上,增加了扩展.感谢被参考的妹子.另外该博客 ...
- matlab获取手机传感器,分享采集Android内置传感器数据到MATLAB的方法
本方法能够实现安卓手机内置的加速度传感器.陀螺仪.磁场数据.角速度传感器及GPS数据采集到MATLAB. 1.硬件准备:安卓手机,电脑,且在同一局域网中: 2.软件准备:安卓手机安装MATLABmob ...
- 读android内置存储芯片数据,WEIPOS开店宝安卓收银机内置存储DIY硬改扩容成功,分享一下心得和体会...
认识众多玩家高手/拆客/DIYer,查阅更多资源,一起学习技术知识 您需要 登录 才可以下载或查看,没有帐号?立即注册 x 帖子比较长,请耐心观看哈! 一.前言 之前在坛子里发过贴,向坛子里的大佬们讨 ...
- 深入浅出CChart 每日一课——快乐高四第九课 于无声处,CChart内置功能介绍之数据存取篇...
笨笨长期以来一直使用Origin软件画图和处理数据,但Origin软件没有编程语言的接口.笨笨开发CChart的一个潜在的目标.是想实现Origin软件的功能.当然这是一个不可能达到的目标.Origi ...
- uniapp内置组件
目录 3.1.视图容器 view scroll-view swiper match-media 3.2.表单组件 form input App平台iOS端软键盘上方横条去除方案 关于软键盘弹出的逻辑说 ...
最新文章
- Ubuntu 14.04安装mysql
- 【PC工具】图片批量添加水印工具,绿色免安装工具软件
- 产品经理必备知识之网页设计系列(三)-移动端适配无障碍设计及测试
- Maven -- group、artifact、package
- 【深度学习】PyTorch深度学习技术生态
- netty web 容器_Netty 实战:如何编写一个麻小俱全的 web 框架
- python更新包列表出错_解决pycharm无法获取安装包文件列表
- keras保存模型_TF2 8.模型保存与加载
- PHP实现一个轻量级容器
- Docker基础知识:Containers,Namespace,CGroups
- vuex的计算属性_vue中vuex的五个属性和基本用法
- 让OSX terminal更出彩
- IRQL的理解和认识
- Windows系统中禁止某应用程序联网操作方法
- 关于光的波粒二象性的解释--答复年少时的疑惑
- 2048php,Phaser实现2048
- label 详细用法
- html大一期末考试,2017年大学英语大一期末考试试题及答案
- python实现电商平台秒杀商品脚本程序
- 如何安装Mac 下的markman破解版
热门文章
- jedis操作set_redis命令行操作set集合和java方式操作set集合
- jsp mysql驱动程序_JSP通过JDBC驱动MySQL数据库方法
- python中if __name__ == '__main__'功能的解析
- 【赠书】图神经网络优质书籍,送你3本进行学习
- 【NLP】 NLP专栏栏主自述,说不出口的话就交给AI说吧
- 【图像分割模型】实例分割模型—DeepMask
- 揭秘7大AI学习板块,这个星球推荐你拥有
- WinForm界面开发之布局控件WeifenLuo.WinFormsUI.Docking的使用
- 找不到atlapp.h的解決方法
- 获得Google搜索字符串中的关键字