gpt4 book ai didi

java - Prepared 语句的 executeQuery() 方法的执行时间与相应的存储过程执行时间

转载 作者:行者123 更新时间:2023-11-29 13:32:30 25 4
gpt4 key购买 nike

我有一些中间件 java 代码在服务器机器上运行,它调用远程机器上 Postgresql 数据库 (9.1) 中的存储过程 insertMessageOne

PreparedStatement sendOne = con.prepareStatement(
"SELECT insertMessageOne(?, ?, ?, ?, ?, ?)");

// Following is the call to Stored procedure through PreparedStatement sendOne
long start = System.nanoTime();
ResultSet rs = sendOne.executeQuery();
long end = System.nanoTime();
long elapsed = (end - start)/1000000;
fileLog.write(System.currentTimeMillis() + ": " + "sendOne.executeQuery(): " + elapsed + "\n");

从日志中可以看出executeQuery耗时几十毫秒。

1385732177920: sendOne.executeQuery(): 13 
1385732178331: sendOne.executeQuery(): 20
1385732178436: sendOne.executeQuery(): 23

但是,对于存储过程 insertMessageOne(代码如下):

CREATE OR REPLACE FUNCTION insertMessageOne(sender_id INT, receiver_id INT, queue_id INT, context INT, priority INT, text varchar(2000))
RETURNS BOOLEAN
AS $$
DECLARE
start timestamp;
stop timestamp;
BEGIN
start = clock_timestamp();
INSERT INTO message(sender_id, receiver_id, queue_id, context, priority, text) VALUES($1,$2,$3,$4,$5,$6);
stop = clock_timestamp();
RAISE NOTICE 'Timestamp: (%) senderId: (%) insertMessageOne: (%)', stop, sender_id, stop - start;
RETURN TRUE;
EXCEPTION
WHEN OTHERS THEN
RAISE NOTICE 'EXCEPTION: INSERT SINGLE-Q MESSAGE FAILED';
RETURN FALSE;
END;
$$ LANGUAGE plpgsql;

在日志中看到的存储过程的执行时间非常短(不到 1-2 毫秒):

NOTICE:  Timestamp: (2013-11-29 15:29:06.012125) senderId: (49) insertMessageOne: (00:00:00.000684)                                                    
NOTICE: Timestamp: (2013-11-29 15:29:06.012848) senderId: (16) insertMessageOne: (00:00:00.000702)
NOTICE: Timestamp: (2013-11-29 15:29:06.013465) senderId: (10) insertMessageOne: (00:00:00.000617)

为什么executeQuery的执行时间比Stored procedure的相应执行时间要大?在这种情况下,网络延迟/带宽应该不是问题,因为代码是在集群中的机器上运行的(彼此直接连接)。我需要考虑一些步骤(在 executeQuery() 调用和存储过程 insertMessageOne() 的实际执行之间)吗?

最佳答案

从函数内部测量的 INSERT 持续时间不包括提交,因为 postgres 从不在函数内部隐式提交(或者甚至是显式提交,如果您尝试,COMMIT 语句会在函数内部引发错误)。

如果 JDBC 连接处于自动提交模式,这意味着从服务器的角度来看,客户端没有发出 SQL BEGIN 开始事务,那么 postgres 将为自己创建一个“查询期间的内部”事务,并在查询结束时提交。

10-20 毫秒是在普通磁盘上提交所需时间的典型值,因此它似乎可以解释您所看到的时差。

如果您将一系列 INSERT 分组在单个事务中,则此延迟应该低得多(如评论中所讨论的那样,仍然存在网络开销)

关于java - Prepared 语句的 executeQuery() 方法的执行时间与相应的存储过程执行时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20307375/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com