【发布时间】:2013-10-25 03:33:23
【问题描述】:
我想知道是否可以以某种方式优化以下脚本。它确实会向磁盘写入很多内容,因为它可能会删除最新的行并重新插入它们。我正在考虑应用类似“在重复键更新上插入...”之类的东西,并发现了一些单行更新的可能性,但我不知道如何在 INSERT INTO ... SELECT query 的上下文中应用它。
CREATE OR REPLACE FUNCTION update_member_search_index() RETURNS VOID AS $$
DECLARE
member_content_type_id INTEGER;
BEGIN
member_content_type_id :=
(SELECT id FROM django_content_type
WHERE app_label='web' AND model='member');
DELETE FROM watson_searchentry WHERE content_type_id = member_content_type_id;
INSERT INTO watson_searchentry (engine_slug, content_type_id, object_id
, object_id_int, title, description, content
, url, meta_encoded)
SELECT 'default',
member_content_type_id,
web_member.id,
web_member.id,
web_member.name,
'',
web_user.email||' '||web_member.normalized_name||' '||web_country.name,
'',
'{}'
FROM web_member
INNER JOIN web_user ON (web_member.user_id = web_user.id)
INNER JOIN web_country ON (web_member.country_id = web_country.id)
WHERE web_user.is_active=TRUE;
END;
$$ LANGUAGE plpgsql;
编辑:web_member、watson_searchentry、web_user、web_country 的架构:http://pastebin.com/3tRVPPVi。
主要是更新watson_searchentry中的title和content列。表上有一个触发器,根据这些列设置列 search_tsv 的值。
watson_searchentry 中的(content_type_id, object_id_int) 是表中的唯一对,但 atm 索引不存在(没有用处)。
该脚本每天最多运行一次,以完全重建搜索索引,偶尔在导入一些数据后运行。
【问题讨论】:
-
用纯 SQL 重写它似乎是可行的。 (您不需要
member_content_type_id变量,它可以通过删除和插入查询中的额外术语获得) WRT upsert:只是一个更新,然后是一个插入(不存在的地方)就可以了。或者使用 RETURNING 构造。 -
你的意思是
'default',,还是DEFAULT? IOW:请添加表定义。 -
@wildplasser:我的意思是“默认”。我添加了更多信息。
标签: sql postgresql optimization plpgsql common-table-expression