当在表格中插入批号时,我们计算基数存在的次数,并根据该计数在新数字的末尾添加 - ##。
我已经删除了大多数逻辑(我们也检查了其他内容)。我也知道这里的逻辑缺陷会跳过-1。
-- Function: stone._lsuniqueid()
-- DROP FUNCTION stone._lsuniqueid();
CREATE OR REPLACE FUNCTION stone._lsuniqueid()
RETURNS trigger AS
$BODY$
DECLARE
_count INTEGER;
BEGIN
-- Obtain the number of occurences of this new ls_number
SELECT COUNT(ls_number) into _count
FROM ls
WHERE ls_number LIKE CAST(NEW.ls_number || '%' AS text);
-- Allow new ls_numbers to be entered as is, otherwise add "-#{count + 1}"
-- to the end of the ls_number
if _count > 0 THEN
NEW.ls_number = NEW.ls_number || '-' || CAST(_count + 1 AS text);
END IF;
RETURN NEW;
END
$BODY$
INSERT INTO ls VALUES (NEXTVAL('ls_ls_id_seq'),7285,UPPER('20151012'));
--> Query returned successfully: one row affected, 391 ms execution time.
计数查询速度很快
SELECT COUNT(ls_number)
FROM ls
WHERE ls_number LIKE CAST('20151012' || '%' AS text);
--> 19ms
为了进行比较,我尝试了类似的触发器,但是针对具有相同行数和相似查询时间的不同表运行计数。
SELECT COUNT(lsdetail_id)
FROM lsdetail
WHERE lsdetail_id > 2433308
--> 20ms
运行相同的插入,对不同的表运行计数会使结果返回20倍。
INSERT INTO ls VALUES (NEXTVAL('ls_ls_id_seq'),7285,UPPER('20151012'));
--> Query returned successfully: one row affected, 20 ms execution time.
ls表有大约250万行
我尝试了几个不同的东西,问题似乎是从我插入的同一个表中选择。
我想知道为什么会发生这种情况,但我也愿意更好地创建“子批次”数字。
谢谢!
答案 0 :(得分:1)
在这里找到答案: http://www.postgresql.org/message-id/27705.1150381444@sss.pgh.pa.us
Re:如何分析功能性能
“明道加斯”写道:是否有可能以某种方式分析功能性能?例如。我们正在使用函数cleanup(),这显然需要花费太多时间来执行,但是我在试图弄清楚什么会减慢速度方面遇到了问题。
当我逐步解释分析功能线时,它表现出相当可接受的性能。
-
你确定你是“解释分析”相同的查询功能 真的在干嘛? 你必须考虑plpgsql是什么的事实 发布是参数化查询,有时限制了 策划者选择好计划的能力。例如,如果你有
declare x int;
begin
...
for r in select * from foo where key = x loop ...
然后真正计划和执行的是“select * from foo 其中key = $ 1“---每个plpgsql变量都被一个参数替换 符号“$ n”。您可以使用准备好的方法为EXPLAIN目的建模 语句:
prepare p1(int) as select * from foo where key = $1;
explain analyze execute p1(42);
如果您在参数化时发现特定查询确实很糟糕, 您可以通过使用EXECUTE强制查询来解决此问题 使用文字常量而不是参数重新计划每次使用:
然后我调查了这个: http://www.postgresql.org/docs/9.1/static/plpgsql-statements.html#PLPGSQL-STATEMENTS-EXECUTING-DYN
<强> 39.5.4。执行动态命令
通常,您需要在PL / pgSQL函数中生成动态命令,即每次执行时都会涉及不同表或不同数据类型的命令。 PL / pgSQL正常尝试缓存命令计划(如第39.10.2节所述)在这种情况下不起作用。为了处理这类问题,提供了EXECUTE语句:
EXECUTE 'SELECT count(*) FROM mytable WHERE inserted_by = $1 AND inserted <= $2'
INTO c
USING checked_user, checked_date;
-
所以最后这是一个更新计数选择的问题:
EXECUTE 'SELECT COALESCE(COUNT(ls_number), 0) FROM ls WHERE ls_number LIKE $1 || ''%'';'
INTO _count
USING NEW.ls_number;