在 sql 中执行计算与在您的应用程序中执行计算的优缺点是什么

新手上路,请多包涵

shopkeeper 表有以下字段:

 id (bigint),amount (numeric(19,2)),createddate (timestamp)

比方说,我有上表。我想获取昨天的记录并通过将金额打印为美分来生成报告。

一种方法是在我的 Java 应用程序中执行计算并执行一个简单的查询

Date previousDate ;// $1 calculate in application

Date todayDate;// $2 calculate in application

select amount where createddate between $1 and $2

然后循环遍历记录并将金额转换为我的 java 应用程序中的美分并生成报告

另一种方法就像在 sql 查询本身中执行计算:

 select cast(amount * 100 as int) as "Cents"
from shopkeeper  where createddate  between date_trunc('day', now()) - interval '1 day'  and  date_trunc('day', now())

然后遍历记录并生成报告

在一种方式中,我所有的处理都是在 java 应用程序中完成的,并触发了一个简单的查询。在其他情况下,所有转换和计算都在 Sql 查询中完成。

上面的用例只是一个例子,在真实的场景中,一个表可能有很多需要类似处理的列。

您能否告诉我哪种方法在性能和其他方面更好,为什么?

原文由 hellojava 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 796
2 个回答

这取决于很多因素——但最关键的是:

  • 计算的复杂性(更喜欢在应用程序服务器上 进行 复杂的处理,因为它可以扩展;而不是数据库服务器,它可以 _扩展_)
  • 数据量(如果您需要访问/聚合大量数据,在数据库服务器上执行将节省带宽,如果聚合可以在索引内完成,则磁盘 io)
  • 方便(sql 不是复杂工作的最佳语言 - 特别是不适合过程性工作,但非常适合基于集合的工作;虽然糟糕的错误处理)

与往常一样,如果您 确实 将数据带回应用服务器,则最小化列和行将对您有利。确保查询经过调整并适当地建立索引将有助于这两种情况。

回复你的笔记:

然后遍历记录

在 sql 中 循环 遍历记录几乎总是错误的——最好编写一个基于集合的操作。

_作为一般规则_,我更喜欢将数据库的工作保持在最低限度“存储此数据,获取此数据”——但是,总是有这样的场景示例,在服务器上进行优雅的查询可以节省大量带宽。

还要考虑:如果这在计算上很昂贵,是否可以将其缓存在某个地方?

如果你想要一个 准确 的“哪个更好”;以两种方式对其进行编码并进行比较(请注意,其中任何一种的初稿都可能未 100% 调整)。但是考虑到典型用法:如果实际上它被一次(分别)调用 5 次,那么模拟一下:不要只比较一个“这些中的 1 个与那些中的 1 个”。

原文由 Marc Gravell 发布,翻译遵循 CC BY-SA 3.0 许可协议

打个比方:如果你想在巴黎买一条 金项链,金匠可以坐在开普敦或巴黎,那是一个技巧和品味的问题。但是你 永远不会 为此将成吨的金矿石从南非运到法国。矿石在采矿现场(或至少在一般区域)加工,只有黄金被运送。应用程序和数据库也应如此。

PostgreSQL 而言,您几乎可以在服务器上非常高效地执行任何操作。 RDBMS 擅长复杂查询。对于程序需求,您可以从各种 服务器端脚本语言 中进行选择:tcl、python、perl 等等。不过,我主要使用 PL/pgSQL

最坏的情况 是为更大集合的每一行重复访问服务器。 (这就像一次运送一吨矿石。)

其次,如果您发送一系列查询,每个查询都取决于之前的查询,而所有这些都可以在服务器上的一个查询或过程中完成。 (这就像用单独的船依次运送黄金和每件珠宝。)

在应用程序和服务器之间来回切换是昂贵的。对于服务器 客户端。尝试减少它,你会赢 - 因此:在必要时使用服务器端过程和/或复杂的 SQL。

我们刚刚完成了一个项目,我们将几乎所有复杂的查询打包到 Postgres 函数中。应用程序传递参数并获取所需的数据集。快速、干净、简单(对于应用程序开发人员而言),I/O 减少到最低限度……一条闪亮的项链,碳足迹低。

原文由 Erwin Brandstetter 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题