Jag tycker att du ska använda elements
tabell:
-
Postgres skulle kunna använda statistik för att förutsäga hur många rader som matchar innan frågan körs, så det skulle kunna använda den bästa frågeplanen (det är viktigare om din data inte är jämnt fördelad);
-
du kommer att kunna lokalisera frågedata med
CLUSTER elements USING elements_id_element_idx
; -
när Postgres 9.2 skulle släppas skulle du kunna dra fördel av endast indexskanningar;
Men jag har gjort några tester för 10 miljoner element:
create table elements (id_item bigint, id_element bigint);
insert into elements
select (random()*524288)::int, (random()*32768)::int
from generate_series(1,10000000);
\timing
create index elements_id_item on elements(id_item);
Time: 15470,685 ms
create index elements_id_element on elements(id_element);
Time: 15121,090 ms
select relation, pg_size_pretty(pg_relation_size(relation))
from (
select unnest(array['elements','elements_id_item', 'elements_id_element'])
as relation
) as _;
relation | pg_size_pretty
---------------------+----------------
elements | 422 MB
elements_id_item | 214 MB
elements_id_element | 214 MB
create table arrays (id_item bigint, a_elements bigint[]);
insert into arrays select array_agg(id_element) from elements group by id_item;
create index arrays_a_elements_idx on arrays using gin (a_elements);
Time: 22102,700 ms
select relation, pg_size_pretty(pg_relation_size(relation))
from (
select unnest(array['arrays','arrays_a_elements_idx']) as relation
) as _;
relation | pg_size_pretty
-----------------------+----------------
arrays | 108 MB
arrays_a_elements_idx | 73 MB
Så å andra sidan är arrayer mindre och har mindre index. Jag skulle göra några 200 miljoner elementtester innan jag tog ett beslut.