Flo*_*rin 21 arrays postgresql
或者更好地说:何时使用数组作为表中的字段数据类型?
哪种解决方案可以提供更好的搜
我避免使用数组有两个原因:
不知道这些链接会持续多久,所以我将粘贴结果如下: http://sqlfiddle.com/#!17/55761/2
太长了;搜索表索引然后连接很快,但是将 GIN 索引(使用 gin__int_ops)添加到具有数组列的单个表中可能会更快。此外,能够匹配“一些”或少量数组值的灵活性可能是更好的选择,例如标记系统。
create table data (
id serial primary key,
tags int[],
data jsonb
);
create table tags (
id serial primary key,
data_id int references data(id)
);
CREATE INDEX gin_tags ON data USING GIN(tags gin__int_ops);
SET enable_seqscan to off;
with rand as (SELECT generate_series(1,100000) AS id)
insert into data (tags) select '{5}' from rand;
update data set tags = '{1}' where id = 47300;
with rand as (SELECT generate_series(1,100000) AS id)
INSERT INTO tags(data_id) select id from rand;
Run Code Online (Sandbox Code Playgroud)
跑步:
select data.id, data.data, data.tags
from data, tags where tags.data_id = data.id and tags.id = 47300;
Run Code Online (Sandbox Code Playgroud)
和
select data.id, data.data, data.tags
from data where data.tags && '{1}';
Run Code Online (Sandbox Code Playgroud)
产量:
Record Count: 1; Execution Time: 3ms
QUERY PLAN
Nested Loop (cost=0.58..16.63 rows=1 width=61)
-> Index Scan using tags_pkey on tags (cost=0.29..8.31 rows=1 width=4)
Index Cond: (id = 47300)
-> Index Scan using data_pkey on data (cost=0.29..8.31 rows=1 width=61)
Index Cond: (id = tags.data_id)
Run Code Online (Sandbox Code Playgroud)
和
Record Count: 1; Execution Time: 1ms
QUERY PLAN
Bitmap Heap Scan on data (cost=15.88..718.31 rows=500 width=61)
Recheck Cond: (tags && '{1}'::integer[])
-> Bitmap Index Scan on gin_tags (cost=0.00..15.75 rows=500 width=0)
Index Cond: (tags && '{1}'::integer[])
Run Code Online (Sandbox Code Playgroud)
我也考虑了这个问题,得出的结论是,当您要消除表联接时使用数组。每个数组中包含的元素数量并不像所涉及表的大小那么重要。如果每个表中只有几千行,那么联接以获得50个子行应该不是什么大问题。如果进入10或100的数千行或数千行,则很可能会开始消耗大量的处理器时间和磁盘I / O。