如何在允许重复键的情况下有效地对键值数据执行相等查询?

时间:2016-10-19 11:24:54

标签: postgresql key-value postgresql-performance external-sorting

我有以下情况:

  1. 数据=大约4亿(string1,string2,得分)元组

  2. 数据大小~20gb,不适合内存。

  3. 数据以csv格式存储在文件中,不按任何方式排序 字段。

  4. 我需要有效地检索具有特定元素的所有元组 字符串,例如所有元组s.t. string1 ='google'。

  5. 如何设计一个系统,以便我能有效地完成这项工作?

    我已经尝试过使用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)
    

0 个答案:

没有答案