我有一个有趣的问题,我和我的同事现在困扰了一段时间。
我在 PostgreSQL-8.3 中有一个 PL/pgSQL 函数(对于那个旧版本,我无法更改),它执行以下四件事:
- 从序列中获取新的序列号 (ID)
- 将几条记录插入到具有该序列号的表中
- 发送一个插入发生的通知信号
- 将 ID 返回给调用者。
简化功能:
CREATE OR REPLACE FUNCTION add_entry(_user_name text, _visible_attr integer[])
RETURNS bigint AS
$BODY$
DECLARE
user_name text := '#' || $1;
user_id bigint;
BEGIN
-- get the ID from the sequence
SELECT nextval('my_sequence') INTO user_id;
-- insert the name (and some other data not shown here) 5x
FOR item IN 1..5
LOOP
INSERT INTO mytable
(id,index,username,visible)
VALUES (user_id,item,user_name,$2[item]);
END LOOP;
-- send notify that an insertion took place
notify my_notify;
RETURN user_id;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
所以,我的同事从他的应用程序中调用了这个函数。他获取返回的 ID 并在他的应用程序中使用另一个线程(DB 池)来调用一个函数,该函数将返回先前使用该 ID 插入的数据。但是,这在第一次不起作用。只有通过第二个请求,他才能选择数据。当函数已经返回时,似乎 INSERT 还没有完成?!
我们检查了多次,数据将正确插入到表中,但不知何故,它的可用速度不如返回值(序列中的 ID)可用!为什么呢?
更新:错误的假设
我进一步检查并将示例简化为一个真正显示问题的简单查询:
select * from mytable where id = (select add_entry('MyTestUser'));
此查询不返回任何行。但是,如果我分两个步骤执行此操作,我可以选择使用 add_entry 函数插入的数据。
我不知道我做错了什么或如何加快插入速度......