从应用程序多次调用数据库过程是不是会影响性能?

Posted

技术标签:

【中文标题】从应用程序多次调用数据库过程是不是会影响性能?【英文标题】:Whether performance will impact when database procedure is called from application many times?从应用程序多次调用数据库过程是否会影响性能? 【发布时间】:2016-01-13 09:28:21 【问题描述】:

在我的项目中,我们从 c++ 应用程序调用 oracle 过程 借助oracle提供的Pro *C/C++库。

我们有一个大程序,我的想法是将程序分成两部分以实现模块化。但他们的建议是调用该程序一次,然后一次性执行所有工作。

我从他们那里得到的原因是它会导致性能影响,因为应用程序与数据库进行多次交互。

我同意,当应用程序连接数据库,调用过程并最终为每个过程调用断开数据库时,会发生上述情况。但是,我们真正要做的是在启动时创建一个连接池,并重用预先连接的数据库连接来与数据库交互。

我的申请信息:

    它是multi-threaded application,每秒处理大约1000个请求,线程池大小为20。目前对于每个请求,我们与数据库通信4次。

编辑:

“PLSQL 和 SQL 之间的切换比其他方式快得多”。 Q1。这与我的实际问题有什么关系?我的问题是将程序分成两个相等的部分。假设我在过程中执行了 4 个查询,我只是将它分成两个过程 a 和过程 b,每个过程将有两个查询。

“调用 PLSQL 的 pro*c 调用会影响性能”。 Q2。你的意思是应用程序(pro *C/C++)和数据库(oracle)之间的通信吗?如果是这样,通信是否会对性能造成很大影响?

在您附加的 ask tom 链接中,“但不要害怕从 PLSQL 调用 SQL - 这是 PLSQL 最擅长的” Q4。当我们从 PLSQL 调用 SQL 时是否会发生上下文切换?因为,按照上面的说法,它似乎对性能没有影响。

【问题讨论】:

您是否对其进行了测量以了解对现实世界的影响? 【参考方案1】:

您的建议是正确的,最好一次执行所有数据库任务。您的方案中有 2 个主要的性能影响

    pro*c 在 SQL 引擎和 PL/SQL 引擎之间的上下文切换以多次运行您的线程。通常是来自客户端应用程序的许多 PL/SQL 调用中的最大问题。 您的 pro*c 应用和数据库引擎之间的通信中的网络堆栈开销 (TNS) - 特别是如果您的应用位于不同的物理主机上。

话虽如此,您正在应用程序端创建一个连接池,TNS 侦听器还应该有一个等待每个网络连接的遗留服务器影子进程池(这是在 listener.ora 中设置的)。

当影子进程已经在等待连接时,OCI 登录/注销非常快,而不是延迟的重要因素 - 我不担心这个,除非服务器上的新影子进程必须启动 - 然后它可能是一个非常昂贵的电话。当您在客户端使用连接池时,这通常不是问题,而只是由于调用中的线程而需要考虑的事情。一旦您耗尽了服务器影子进程池,如果 TNS 侦听器必须启动更多的服务器影子进程,您会发现性能大幅下降。

编辑以回答新问题:

    非常相关。如前所述,您应该尽量减少 C++ 应用程序中的 plsql 和 sql 调用量。 C++ 应用程序调用中的每个 PLSQL 调用调用 SQL 引擎,然后调用 PLSQL 引擎进行过程调用。因此,如果您将过程分成 2 个 - 您将 SQL 到 PLSQL 上下文切换加倍,这是 Tom Kyte 文章和我自己的个人经验所概述的更昂贵的切换。

    答案在 1 中。但正如我之前所说,除非您的主机位于不同的物理网络以及您正在传输的数据类型不同,否则通信开销是第二位的。例如,大型 C++ 对象参数和具有许多调用的大型 Oracle 结果集显然会影响往返行程的通信延迟。请记住,随着更多 PLSQL 调用,您还会为每个连接和结果集的设置添加更多 SQLNET 流量。

    没有3.问题

    PLSQL 引擎中的 PLSQL 到 SQL 可以忽略不计,所以不要挂断它。将所有 SQL 调用放在 1 个 PLSQL 调用中,以获得最大的性能吞吐量。不要为了更雄辩而牺牲性能而拆分调用。

【讨论】:

我明白了,plsql引擎不同,sql引擎也不同。由于两个引擎不同,上下文切换需要时间。考虑一下我将我的程序分成两个相等的部分。根据我不理解的上下文切换,过程中的每个 sql 查询都会发生。因此,即使我们拆分过程上下文切换也会发生相同的次数。我的理解正确吗? 您几乎是正确的——PLSQL 和 SQL 之间的切换比其他方式快得多。所以在你的 1 或 2 个 PLSQL 调用中有几个 SQL 调用我不会太担心。然而,有许多调用 SQL 的 pro*c 调用,然后是一个 PLSQL 例程等等——我见过很多次,这对性能造成了很大的影响。更多信息在这里:asktom.oracle.com/pls/apex/… 请查看新的编辑。我相信通过询问汤姆的文章,这应该可以回答您的问题,如果您将其标记出来,我们将不胜感激。 @Rob Mascaro 非常感谢您的耐心等待。我现在明白了。我以为 C++ 应用程序会直接调用 PL/SQL 引擎。我现在明白它会调用 SQL 引擎,而后者又会调用 PL/SQL 引擎。但我现在很好奇为什么会这样称呼它?也发布了另一个与此相关的问题.. ***.com/questions/35402262/…

以上是关于从应用程序多次调用数据库过程是不是会影响性能?的主要内容,如果未能解决你的问题,请参考以下文章

避免在 Oracle 过程中频繁调用同一视图

将参数传递给 Perl 子例程时,是不是会影响数据复制性能?

在 ios 应用程序中从磁盘加载大图像

从同一个线程多次调用 sub

解构 getState() (在 Redux Think 中)而不是多次调用它是不是有影响?

使用存储过程进行数据分页