速来报名!AICon北京站鸿蒙专场~ 了解详情
写点什么

在关系型数据库中运行计算

  • 2014-03-21
  • 本文字数:1577 字

    阅读完需:约 5 分钟

近日, JOOQ 的官方博客上发表了一篇文章,针对Stack Overflow 上“如何使用Hibernate 映射处理庞大的数据表”这样一个问题,作者认为有必要提醒下开发人员,不要犯 Java 开发人员编写 SQL 时常犯的十个错误中的第二项错误:在 Java 内存中处理数据。

Stack Overflow 上的问题可以归结为:从下面的中型表中计算出每个应用程序 ID 对应多少个状态为 0 或 1 的文档。用 Hibernate 该如何实现?

复制代码
AppID | DocID | DocStatus
------+-------+----------
1 | 100 | 0
1 | 101 | 1
2 | 200 | 0
2 | 300 | 1
... | ... | ...

“NO! 不要用 Hibernate!你要用 SQL。Es-Queue-EI!……”,作者认为,有许多简单的方法可以让 SQL 服务器来运行这种查询,而且时间很短,又不用在聚合之前将所有的数据加载到 Java 内存。他分别使用 GROUP BY、嵌套查询、SUM()和 PIVOT 给出了四种实现方式,并认为其中任何一种的性能都会在数量级上超过任何基于 Java 的实现。文章的结尾这样写道:

任何时候,只要合适就使用 SQL! 能用 SQL 的地方远比你想象的多。

该文在 reddit 用户之间引发了激烈的讨论。ggtsu_00 认为:

……如果计算减少了返回结果的行数,那么最好在数据库里计算。不过,许多计算是后处理或格式修改,这些最好是在应用服务器上进行。

对于 ggtsu_00 的观点,lukasedar 进行了补充,认为“争论的焦点是通过网络在处理数据的节点之间传输的数据量”。Grauenwolf 则表示,如果将该观点中的“返回结果的行数”改为“返回结果的行数或列数”,那么他也赞同。而该观点的后半部分则引发了进一步的争论。ItsMeCaptainMurphy 认为:

这要看你做什么,构建数据库通常是用来尝试并行的,对于行级操作尤其如此。……而且你的数据库服务器的性能可能比 Web 服务器或客户端更强大。那么,有些事情确实是最好在应用程序端做,但并不是所有情况,甚至不是多数情况。

不过,emn13 则认为这与数据库服务器的性能无关,而与代码性能相关:

本地或近似本地代码的性能通常是 SQL 的 1000 倍,而且可能更高。即使是像 Ruby 或 Python 这样相当慢的语言在简单表达式求值方面也可能比大部分 SQL 服务器要快。

SQL 不是一个很好的通用计算器。如果计算没能减少返回结果的行数,就不能想当然地认为一台高性能的数据库服务器实际上会超过一部手机。

……

总而言之,由于大部分计算都很简单,所以没有减少数据也没关系。但当计算代价很高时,SQL 通常是缓慢的。

为了使自己的观点更有说服力,他结合自身的经验作了进一步的说明:

1000 倍这个数量级是我在 MS SQL SERVER 上实现一个有向图节点计分算法时观察到的,不是假想的场景。

Ulukai 对上述观点表示了赞同,他还补充说

如果有非常复杂的逻辑需要执行,那么你应该仔细考虑。比如,我不会在数据库代码中执行“最短路径”算法,除非它获得原生支持。

在关系型数据库中进行计算,除了应用场景的问题,还有知识结构和使用习惯的问题。人们已经花了很多时间和精力来学习 ORM 框架的所有最细微的细节,所以他们真的不喜欢他们应该更好地学习 SQL 这样的建议。但 crimson_chin 认为:

学习任何一个而不学习另一个都会让你处于不利地位。如果学了 SQL 没有学 ORM,那你就要面临代码可能过于冗长且难以维护的风险。如果你学了 ORM 没有学 SQL,那么你就要面临自我折磨的风险,因为一个查询为了获取项的名称列表却拉回了 200 列。

但同时,他认为数据库代码难以测试、管理和维护。因此,只有在可以明确地知道是最佳实践的时候,他才会使用数据库的特性来进行开发。

总之,JOOQ 的博文虽然引发了一场讨论,但文章本身的内容似乎没有多大的争议。至于什么时候应该在关系型数据库中进行计算,什么时候应该在应用程序端进行计算,大家也有一定的共识。具体做法则要视应用场景,并根据 SQL、ORM 各自的优缺点进行综合分析和测试,而这当然离不开对 SQL 和 ORM 的学习和使用经验。

2014-03-21 20:212197
用户头像

发布了 256 篇内容, 共 86.3 次阅读, 收获喜欢 12 次。

关注

评论

发布
暂无评论
发现更多内容

大厂经验谈之OKR目标管理

巫山老妖

数仓实践丨从CU入手优化HStore表

华为云开发者联盟

数据库 后端 华为云 华为云开发者联盟 华为云GaussDB(DWS)

SmartZipper for Mac(专业压缩解压工具)v2.10激活版

iMac小白

Things3 for Mac(日程和任务管理工具)v3.20中文免激活版

iMac小白

李林甫,天才制度大师还是庸才裱糊匠?

酱紫的小白兔

从smallredbook.item_get_video看电商行业的发展趋势

技术冰糖葫芦

API 文档

Disk Graph for Mac(磁盘空间分析工具)v3.0.2激活版

iMac小白

GM CHM Reader Pro for mac(CHM阅读器)v2.5.3激活版

iMac小白

深入解析Python并发编程的多线程和异步编程

华为云开发者联盟

Python 多线程 开发 华为云 华为云开发者联盟

抖音详情API:API请求格式与参数详解

技术冰糖葫芦

API 接口

CSS图像边框:Interop 2023的一个重点领域

南城FE

CSS 前端 图像边框

Git 教程:解密 .gitignore 文件、合并分支、解决冲突、及 Git 帮助

小万哥

git 程序人生 编程语言 软件工程 后端开发

Gateway API与Ingress:Kubernetes网络的未来

Gingxing

kong api 网关 Kong 网关 消息网关 Kong Gateway

GraphicConverter 12 for Mac(图片浏览器)v12.1.1(6434)中文激活版

iMac小白

Tidy Up for Mac(重复文件查找清理工具)v6.0.4激活版

iMac小白

一文搞懂设计模式—享元模式

Java随想录

Java 设计模式

牛刀专业低代码平台开发实战—三会议案

牛刀专业低代码

低代码 起步牛刀低代码 牛刀低代码 牛刀专业低代码 牛刀低代码paas平台

构建企业多维模型,助力财务战略规划

智达方通

战略规划 全面预算 多维模型 财务规划

ubuntu安装指定版本:nodejs

百度搜索:蓝易云

Linux ubuntu 运维 Node 云服务器

Lights Out for Mac(扩展节能器)v3.2修复激活版

iMac小白

OpenAI和谷歌,AI对线中的飞驰人生

脑极体

AI

docker安装minio

百度搜索:蓝易云

Docker Linux 运维 Minio 云服务器

极狐GitLab 16.9 重磅发布,赶快来 pick 你喜爱的功能吧~

极狐GitLab

Tower for Mac(强大的Git客户端)v10.4注册激活版

iMac小白

Screen Recorder by Omi Mac(Omi录屏专家‬)v1.3.8激活版

iMac小白

朴素的DevOps价值观

华为云PaaS服务小智

软件开发 华为云

Programming Abstractions in C阅读笔记:p303-p305

codists

HTTP/1.1协议中的八种请求

百度搜索:蓝易云

云计算 Linux 运维 HTTP 云服务器

Native SQLite Manager for Mac(极简SQLite数据库管理器)v1.27.3激活版

iMac小白

在关系型数据库中运行计算_数据库_马德奎_InfoQ精选文章