当从应用程序多次调用数据库过程时,性能是否会受到影响



在我的项目中,我们使用借助oracle提供的Pro*C/C++库。

我们有一个大的过程,我的想法是将这个过程一分为二,以实现模块化。但他们的建议是一次性调用该程序,并一次性执行所有工作。

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

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

有关我的应用程序的信息:

  1. 它是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. pro*c在SQL引擎和PL/SQL引擎之间的上下文切换,以多次运行线程。通常是来自客户端应用程序的许多PL/SQL调用中最大的问题
  2. pro*c应用程序和数据库引擎之间通信的网络堆栈开销(TNS),尤其是当您的应用程序位于不同的物理主机上时

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

当影子进程已经在等待连接时,OCI登录/注销非常快,并且不是延迟的一个很大因素——我不担心这一点,除非服务器上必须启动一个新的影子进程——那么这可能是一个非常昂贵的调用。当您在客户端使用连接池时,这通常不是一个问题,只是需要考虑的问题,因为您的调用中有线程。一旦耗尽了服务器影子进程池,如果TNS侦听器必须启动更多的服务器影子进程,您将注意到性能的巨大下降。

编辑以回答新问题:

  1. 这是非常相关的。如前所述,您应该尽量减少C++应用程序中plsql和sql调用的数量。C++应用程序调用中的每个PLSQL调用都会调用SQL引擎,然后SQL引擎会为过程调用调用PLSQL引擎。因此,如果您将过程拆分为2个,那么您将加倍使用SQL到PLSQL上下文开关,这是Tom Kyte文章和我个人经验中概述的更昂贵的开关。

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

  3. 没有3。问题

  4. PLSQL引擎中的PLSQL到SQL是可以忽略不计的,所以不要挂断它。将所有SQL调用放在一个PLSQL调用中,以获得最大的性能吞吐量。不要为了在昂贵的性能上更有说服力而分散电话。

相关内容

最新更新