Function 该postgres功能是否具有成本效益,还是仍需清理

Function 该postgres功能是否具有成本效益,还是仍需清理,function,postgresql,performance,nested-loops,Function,Postgresql,Performance,Nested Loops,postgres数据库中有两个表。 英语世界和英语世界 第一个表包含国际、机密、开机、冷却器等词 我已经编写了从english_all中获取单词的函数,然后对每个单词执行for循环,以获取未插入english_glob表中的单词列表。单词表就像 I In Int Inte Inter .. b bo boo boot .. c co coo cool etc.. 出于某种原因,在插入到english_all表的过程中添加了zwnj(零宽度非接合器)。 但在函数中,我用regexp\u repl

postgres数据库中有两个表。 英语世界和英语世界

第一个表包含国际、机密、开机、冷却器等词

我已经编写了从english_all中获取单词的函数,然后对每个单词执行for循环,以获取未插入english_glob表中的单词列表。单词表就像

I
In
Int
Inte
Inter
..
b
bo
boo
boot
..
c
co
coo
cool
etc..
出于某种原因,在插入到english_all表的过程中添加了zwnj(零宽度非接合器)。 但在函数中,我用regexp\u replace删除该字符

用于循环测试的Postgres函数取两个参数min和max,基于此,我从英语表中选择单词

函数代码如下

DECLARE
inMinLength ALIAS FOR $1;
inMaxLength ALIAS FOR $2;
mviews RECORD;
outenglishListRow english_word_list;--custom data type eng_id,english_text
BEGIN
FOR mviews IN SELECT id,english_all_text FROM english_all where wlength between inMinLength and inMaxLength 
ORDER BY english_all_text limit 30 LOOP

FOR i IN 1..char_length(regexp_replace(mviews.english_all_text,'(‌)$','')) LOOP
    FOR outenglishListRow IN
        SELECT distinct on (regexp_replace((substring(mviews.english_all_text from 1 for i)),'(‌)$','')) mviews.id,
        regexp_replace((substring(mviews.english_all_text from 1 for i)),'(‌)$','') where 
        regexp_replace((substring(mviews.english_all_text from 1 for i)),'(‌)$','') not 
        in(select english_glob.english_text from english_glob where i=english_glob.wlength)
        order by regexp_replace((substring(mviews.english_all_text from 1 for i)),'(‌)$','')
    LOOP
    RETURN NEXT outenglishListRow;
    END LOOP;


END LOOP;
END LOOP;
END;
一旦我得到单词列表,我将把它插入另一个表english_glob。 我的问题是,是否有任何东西可以添加到函数中或从函数中删除,以提高效率

编辑 假设所有的表都有这样的单词

  • 页脚、结算、问题、溢出、数据库、王国
如果inMinLength=5,inmaxLength=7 然后在外环

  • 页脚、定居、王国
将被选中。 对于以上3个单词,内部两个循环将应用于获得以下单词

  • f、 fo,foo,foot,foote,footer,s,se,set,sett,sett .... 等等
在最后的过程中,粗体字将输入english_glob,并使用另一个参数(如1)表示它是正确的字,并存储在english_glob表的另一个字段中。剩余的单词将与另一个参数0一起存储,因为在下一次调用中,不应再次提取保存在数据库中的单词

编辑2: 这是一个完整的代码

CREATE TABLE english_all
(
id serial NOT NULL,
english_all_text  text NOT NULL,
wlength integer NOT NULL,
CONSTRAINT english_all PRIMARY KEY (id),
CONSTRAINT english_all_kan_text_uq_id UNIQUE (english_all_text)
)

CREATE TABLE english_glob
(
id serial NOT NULL,
english_text  text NOT NULL,
is_prop integer default 1,
CONSTRAINT english_glob PRIMARY KEY (id),
CONSTRAINT english_glob_kan_text_uq_id UNIQUE (english_text)
)

insert into english_all(english_all_text,wlength) values ('ant',char_length('ant')),('forget',char_length('forget')),('forgive',char_length('forgive'));
对于参数为3和6的函数调用,应获取空闲行

a
an
ant
f
fo
for
forg
forge
forget
下一步是基于上述行插入到另一个表

insert into english_glob(english_text,is_prop) 
values 
('a',1),('an',1),
('ant',1),('f',0),
('fo',0),('for',1),
('forg',0),('forge',1),
('forget',1),
下一次使用参数3和7调用函数时,应获取空闲行。(因为f、fo、for、forg都是在english_glob表中输入的)


您可以在一句话中完成:

SELECT  english_all_text, part,
        part IN
        (
        SELECT  english_text
        FROM    english_glob
        ) AS found
FROM    (
        SELECT  *, SUBSTRING(english_all_text, 1, generate_series(1, LENGTH(english_all_text))) AS part
        FROM    english_all
        WHERE   LENGTH(english_all_text) BETWEEN 5 AND 7
        ) q
要检查的一些示例数据:

WITH    english_all(english_all_text) AS
        (
        SELECT  unnest('{footer,settle,question,overflow,database,kingdom}'::text[])
        ),
        english_glob(english_text) AS
        (
        SELECT  unnest('{foot,footer,set}'::text[])
        )
SELECT  english_all_text, part,
        part IN
        (
        SELECT  english_text
        FROM    english_glob
        ) AS found
FROM    (
        SELECT  *, SUBSTRING(english_all_text, 1, generate_series(1, LENGTH(english_all_text))) AS part
        FROM    english_all
        WHERE   LENGTH(english_all_text) BETWEEN 5 AND 7
        ) q
更新:

如果您只需要返回其部分不在列表中的单词,请使用以下方法:

SELECT  part
FROM    (
        SELECT  *, SUBSTRING(english_all_text, 1, generate_series(1, LENGTH(english_all_text))) AS part
        FROM    english_all
        WHERE   LENGTH(english_all_text) BETWEEN 5 AND 7
        ) q
WHERE   part NOT IN
        (
        SELECT  english_text
        FROM    english_glob
        )

@我根本不工作。查询只是返回english_all表中的所有行。MinLength和inMaxLength中的FUNCTION参数也不包括在查询本身中。@kiranking:您可以发布两个表中的一些示例数据和预期输出吗?@Quassnoi请检查编辑的问题。数据获取没有问题,但我关心的是嵌套for循环。它是有效的还是我仍然需要调整它。@kiranking:请查看查询更新。请您发布您所关注的结果集,而不是口头描述:口头描述可能会让人困惑。@我用更详细的结果集编辑了这篇文章。如果您使用循环逻辑,那么在查看“最快方式”时,您并不是在使用“最快方式”。在可能的情况下,尝试重新使用直接SQL,在大多数情况下,这是可能的,并且将是最快的。边缘情况下,您可能需要使用一些PL。谢谢您的代码。您正在将
1
插入
is_prop
中,用于
a
an
ant
用于
伪造
忘记
PostgreSQL
如何知道它们是正确的英语单词并用
1
标记它们?
SELECT  part
FROM    (
        SELECT  *, SUBSTRING(english_all_text, 1, generate_series(1, LENGTH(english_all_text))) AS part
        FROM    english_all
        WHERE   LENGTH(english_all_text) BETWEEN 5 AND 7
        ) q
WHERE   part NOT IN
        (
        SELECT  english_text
        FROM    english_glob
        )