我有以下情况:
数据=大约4亿(string1,string2,得分)元组
数据大小~20gb,不适合内存。
数据以csv格式存储在文件中,不按任何方式排序 字段。
我需要有效地检索具有特定元素的所有元组 字符串,例如所有元组s.t. string1 ='google'。
如何设计一个系统,以便我能有效地完成这项工作?
我已经尝试过使用B树索引和GIN索引的postgresql,但是每个查询的速度不够快(> 20-30秒)。
理想情况下,我需要一个解决方案,它按字符串1对元组进行排序,以排序方式存储它们,然后运行二进制搜索,然后顺序扫描以进行检索。但是,我不知道哪个数据库或系统实现了这样的功能。
更新: 这是postgres的详细信息:
我使用COPY命令将数据批量加载到postgres中。然后我在string1上创建了两个索引,一个是b-tree,另一个是GIN。但是,postgres没有使用其中任何一个。
创建表格:
CREATE TABLE mytable(
string1 varchar primary key, string2 varchar, source_id integer REFERENCES sources(id), score real);
CREATE EXTENSION IF NOT EXISTS pg_trgm;
CREATE INDEX string1_gin_index ON mytable USING gin (string1 gin_trgm_ops);
CREATE INDEX string1_index ON mytable(lower(string1));
查询计划:
isa=# EXPLAIN ANALYZE VERBOSE select * from mytable where string1 ilike 'google';
QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------------------------
Bitmap Heap Scan on public.mytable (cost=235.88..41872.81 rows=11340 width=29) (actual time=20234.765..25566.128 rows=30971 loops=1)
Output: hyponym, string2, source_id, score
Recheck Cond: ((mytable.string1)::text ~~* 'google'::text)
Rows Removed by Index Recheck: 34573
-> Bitmap Index Scan on string1_gin_index (cost=0.00..233.05 rows=11340 width=0) (actual time=20218.263..20218.263 rows=65544 loops=1)
Index Cond: ((mytable.string1)::text ~~* 'google'::text)
Total runtime: 25568.209 ms
(7 rows)
isa=# EXPLAIN ANALYZE VERBOSE select * from isa where string1 = 'google';
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------
Seq Scan on public.mytable (cost=0.00..2546373.30 rows=3425 width=29) (actual time=11692.606..139401.099 rows=30511 loops=1)
Output: string1, string2, source_id, score
Filter: ((mytable.string1)::text = 'google'::text)
Rows Removed by Filter: 124417194
Total runtime: 139403.950 ms
(5 rows)