Небольшое дополнение к ответу Эрвина - иногда подзапрос с unnest
может быть даже дешевле, чем боковое соединение.
Я использовал определение таблицы от ответа Эрвина и наполнил его:
t=# insert into t select '{1}'::int[]||g,'{1}'::int[]||g from generate_series(1,9999,1) g;
INSERT 0 9999
t=# select * from t order by ctid desc limit 1;
link_ids | length
----------+----------
{1,9999} | {1,9999}
(1 row)
затем анализировать LATERAL JOIN:
t=# explain analyze select link_ids,max(r) from t, unnest(length) r where link_ids = '{1,9999}' group by 1;
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------
GroupAggregate (cost=0.29..4.81 rows=1 width=33) (actual time=0.030..0.030 rows=1 loops=1)
-> Nested Loop (cost=0.29..4.30 rows=100 width=33) (actual time=0.025..0.027 rows=2 loops=1)
-> Index Scan using t_pkey on t (cost=0.29..2.30 rows=1 width=58) (actual time=0.015..0.016 rows=1 loops=1)
Index Cond: (link_ids = '{1,9999}'::integer[])
-> Function Scan on unnest r (cost=0.00..1.00 rows=100 width=4) (actual time=0.007..0.007 rows=2 loops=1)
Total runtime: 0.059 ms
(6 rows)
и попробуйте подзапрос:
t=# explain analyze select link_ids, (select max(r) from unnest(length) r) from t where link_ids = '{1,9999}';
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------
Index Scan using t_pkey on t (cost=0.29..3.56 rows=1 width=58) (actual time=0.030..0.031 rows=1 loops=1)
Index Cond: (link_ids = '{1,9999}'::integer[])
SubPlan 1
-> Aggregate (cost=1.25..1.26 rows=1 width=4) (actual time=0.011..0.011 rows=1 loops=1)
-> Function Scan on unnest r (cost=0.00..1.00 rows=100 width=4) (actual time=0.008..0.008 rows=2 loops=1)
Total runtime: 0.060 ms
(6 rows)
и, наконец, убедитесь, что То же самое:
t=# select link_ids, (select max(r) from unnest(length) r)
from t
where link_ids = '{1,9999}';
link_ids | max
----------+------
{1,9999} | 9999
(1 row)
t=# select link_ids,max(r)
from t, unnest(length) r
where link_ids = '{1,9999}'
group by 1;
link_ids | max
----------+------
{1,9999} | 9999
(1 row)
Почему ваши столбцы массивы? Это выглядит очень плохой дизайн схемы. – Falmarri
Чтобы увеличить комментарий от @Falmarri - существует набор формальных правил (называемых нормальными формами), которые описывают, как должна выглядеть схема реляционных баз данных, чтобы предотвратить множество проблем - считается разумным соответствовать по меньшей мере первые три - ваша схема не соответствует первой, так как ячейки вашей таблицы не хранят атомные значения. Вы должны использовать таблицы для хранения списков. – lared
Я знаком с нормальными формами. Это результат рекурсивного запроса, который я хотел бы продолжить. – jaynp