在Before触发器功能中,我尝试优化使用表格的数组交集的SELECT:
select into matching_product * from products where global_ids && NEW.global_ids
以上是在执行一些适度的批量插入时将cpu挂在100%。 (如果没有上面的触发功能选择,则cpu下降到~5%)
我确实在global_ids
上定义了一个GIN索引,但这似乎不起作用。
还有其他优化方法吗?例如:我是否应该继续在产品和global_ids之间建立N-M关系并进行一些连接以获得相同的结果?
编辑
似乎使用了GIN索引,但它仍然很慢。不知道我能期待什么,(YMMV和所有这些),但桌子有~200,000项。执行如下查询需要300毫秒。我觉得这应该是即时的。
select * from products where global_ids && '{871712323629}'
对上述节目做了解释:
Bitmap Heap Scan on products (cost=40.51..3443.85 rows=1099 width=490)
Recheck Cond: (global_ids && '{871712323629}'::text[])
-> Bitmap Index Scan on "global_ids_GIN" (cost=0.00..40.24 rows=1099 width=0)
Index Cond: (global_ids && '{871712323629}'::text[])
表定义,删除了不相关的列
CREATE TABLE public.products
(
id text COLLATE pg_catalog."default" NOT NULL,
global_ids text[] COLLATE pg_catalog."default",
CONSTRAINT products_pkey PRIMARY KEY (id)
)
WITH (
OIDS = FALSE
)
TABLESPACE pg_default;
索引
CREATE INDEX "global_ids_GIN"
ON public.products USING gin
(global_ids COLLATE pg_catalog."default")
TABLESPACE pg_default;
答案 0 :(得分:0)
我想不出为什么这样的查询在PL / pgSQL函数中应该有不同的行为的原因;我的实验表明它没有。
对查询运行EXPLAIN (ANALYZE, BUFFERS)
,就像在函数内部多次运行一样,以便对期望的持续时间有一个很好的估计。
在类似表上的批量插件上运行EXPLAIN (ANALYZE, BUFFERS)
,而不用触发器来测量堆插入和索引维护所需的时间。
添加这些值并乘以您在批处理中插入的行数。
如果你的体验时间大致相同,那就没有什么可以解决的了。
如果最终得到“有损”位图索引扫描(查看EXPLAIN (ANALYZE, BUFFERS)
输出),则可以通过增加work_mem
来提升性能。