Как эффективно выполнить запрос на равенство для данных значения ключа с разрешенными дублирующимися ключами?

У меня следующая ситуация:

  1. Данные = около 400 миллионов (строка1, строка2, оценка) кортежей

  2. Размер данных ~ 20 ГБ, не помещается в памяти.

  3. Данные хранятся в файле в формате csv и не сортируются ни по одному полю.

  4. Мне нужно эффективно получить все кортежи с определенной строкой, например, все кортежи st string1 = 'google'.

Как мне спроектировать систему так, чтобы я мог сделать это эффективно?

Я уже пробовал postgresql с индексом B-дерева и индексом GIN, но они недостаточно быстры (> 20-30 секунд) для запроса.

В идеале мне нужно решение, которое сортирует кортежи по string1, сохраняет их в отсортированном виде, а затем запускает бинарный поиск с последующим последовательным сканированием для поиска. Но я не знаю, какая база данных или система реализует такую ​​функциональность.

ОБНОВЛЕНИЕ: Вот детали postgres:

Я загрузил данные в postgres, используя команду COPY. Затем я создал два индекса для string1, одно b-дерево и один 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 ответов

Другие вопросы по тегам