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

2022-08-31 06:52:53

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查询中完成的。

上面的用例只是一个示例,在实际场景中,一个表可以有许多需要处理类似类型的列。

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


答案 1

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

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

与往常一样,如果您确实将数据带回应用程序服务器,则最小化列和行将对您有利。确保对查询进行优化并相应地编制索引都将有助于这两种情况。

回复您的笔记:

,然后遍历记录

在sql中,遍历记录几乎总是错误的做法 - 编写基于集合的操作是首选。

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

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

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


答案 2

让我用一个比喻:如果你想在巴黎买一条金项链,金匠可以坐在开普敦或巴黎,那是一个技巧和品味的问题。但你永远不会为此从南非向法国运送大量金矿石。矿石在采矿现场(或至少在一般区域)加工,只有黄金被运输。对于应用和数据库来说,情况也同样如此。

PostgreSQL而言,您几乎可以在服务器上非常有效地做任何事情。RDBMS 擅长复杂的查询。对于过程需求,您可以从各种服务器端脚本语言中进行选择:tcl,python,perl等等。不过,大多数情况下我使用PL / pgSQL

最坏的情况是,对于较大集合的每一行,重复转到服务器。(这就像一次运送一吨矿石一样。

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

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

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


推荐