【发布时间】:2017-06-22 08:10:20
【问题描述】:
样本数据
我有 2 个表需要加入到包含整数数组的列上。
CREATE TABLE table_array_1 (key1 int, values1 int[]);
CREATE TABLE table_array_2 (key2 int, values2 int[]);
一个表的行数很少,但数组大小很大:
DO $function$
DECLARE
i int := 0;
BEGIN
WHILE i < 100 LOOP
INSERT INTO table_array_1 (key1, values1) values(random(1, i), (SELECT array_agg(random(3000000, 4000000)) FROM (SELECT generate_series(1, random(1, 2000))) lp));
i := i + 1;
END LOOP;
END;
$function$
第二个表有更多的行,但数组大小较小:
DO $function$
DECLARE
i int := 0;
BEGIN
WHILE i < 1000 LOOP
INSERT INTO table_array_2 (key2, values2) values(random(1, i), (SELECT array_agg(random(3000000, 4000000)) FROM (SELECT generate_series(1, random(1, 50))) lp));
i := i + 1;
END LOOP;
END;
$function$
函数random(int,int)返回范围内的随机整数:
CREATE OR REPLACE FUNCTION random(int, int)
RETURNS int
LANGUAGE sql
AS $function$
SELECT ($1 + ($2 - $1) * random())::int;
$function$
测试
我最初尝试像 explain 那样加入他们:
SELECT t1.key1, t2.key2
FROM table_array_1 t1
JOIN table_array_2 t2 ON t2.values2 && t1.values1
但它比 explain 慢得多(大约 100 倍):
SELECT DISTINCT t1.key1, t2.key2
FROM (SELECT key1, unnest(values1) AS values1 FROM table_array_1) t1
JOIN (SELECT key2, unnest(values2) AS values2 FROM table_array_2) t2
ON t2.values2 = t1.values1
这些表上没有索引,使用GIN 的成本太高而无法使用。 GiST 并没有改进它。这是假设我会使用 intarray 扩展名。
问题
为什么unnest + distinct 更快?
我可以提高数组比较运算符方法的性能或使用不涉及unnest + distinct 的其他方法吗?我正在寻找性能改进,常识告诉我这两个操作应该更慢。
【问题讨论】:
标签: performance postgresql postgresql-9.6