Задать вопрос

Как организовать быстрый поиск по 78 млн строк?

Имеется csv файл в котором около 78 млн строк. Как максимально быстро организовать поиск по этим строкам?
На практике меня интересует всего один столбец, из шести имеющихся в нем. Я могу перенести этот столбец в текстовый документ, если это ускорит поиск.

Я так понимаю, что по идее нужно загрузить этот файл в оперативную память, что бы он постоянно был открытый в ней для наиболее быстрого поиска строк.
Необходимо добиться хотя бы несколько 10-20 миллионов поисков в секунду. Что можете посоветовать для решения этой задачи? В чем хранить, как искать, какое лучше для этого использовать железо?
Предпочитаемые языки python или C#.
  • Вопрос задан
  • 1501 просмотр
Подписаться 9 Средний 2 комментария
Решения вопроса 2
Зависит от того какой поиск и какие данные.
Опять же - если данных уж очень много, то вряд ли получится всё в ОЗУ загрузить
Если по точному соответствию, и все они уникальные - используй хэш таблицы.
Если они сортируемые - отсортируй и используй бинарный поиск.
Если нужен полнотекстовый/нечёткий поиск - проще взять стороннюю СУБД.
Ответ написан
@rPman
На любом языке программирования, желательно c++, реализуешь следующее приложение, использующее map или аналогичную структуру следующим образом.

В качестве ключа - хеш от искомого значения
В качестве значения - список структур, в котоых пара искомое значение (с возможностью выставить null) + возвращаемое значение (идеально может быть смещение в файле csv где начинается нужная строка). Возможно вместо списка использовать еще один map (значение => смещение или даже значение => список смещений, если искомое поле не уникально)
Map<hash,List<{value,offset}>> или Map<hash,Map<value,List<offset>>>

Тогда первоначальное наполнение просто считает хеши ключа и заполняет в возвращаемые значение смещение соответствующих строк в csv файле
Затем вторым проходом, для тех записей где случились коллизии хеша и список возвращаемых значений больше 1, прописать искомое значение либо его хеш (с другим алгоритмом, если не боишься двойных коллизий)

Затем организуешь поисковый метод который будет принимать поисковые запросы и складывать в очередь (thread safe) ответы (id запроса + смещение строки в csv либо null если не найдено). Метод просто считает хеш искомой строки и берет в map нужный список ответов, если их больше 1 то последовательно сравнивае

Параллельным потоком либо с асинхронно считываешь csv строки, на основе этой очереди (если диск hdd то лучше сортировать порядок чтения записей из файла по смещению, если записи в csv очень короткие, сотня другая байт, то сортировать имеет смысл и для ssd)

Если правильно подобрать хеш для искомого значения, то скорость поиска даже на слабых машинах будет сотни миллионов в секунду и будет фактически упираться в скорость чтения csv с диска.
-------------
Готовые базы данных будут хранить в памяти значения искомого поля, что может оказаться накладно, когда как указанный алгоритм позволит подобрать такой хеш, чтобы коллизий его было сильно мало и не требовалось бы хранить значение в принципе.

само собой можно считать хеш самому и использовать готовую базу данных но тогда какой смысл в ней если все делать самому.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 3
dimonchik2013
@dimonchik2013
non progredi est regredi
  • Clickhouse,
  • Sphinx/Manticore search
  • Reindexer
  • грамотный Сишник/Растщик/Гофер
Ответ написан
Комментировать
2ord
@2ord
Чтобы не городить огород, достаточно импортировать в SQLite. Ну и, добавить индекс на нужную колонку. Если нужно, там есть и полно-текстовый поиск.
Ответ написан
uvelichitel
@uvelichitel
habrahabr.ru/users/uvelichitel
  • Отразить файл в память memory-mapped-file System.IO.MemoryMappedFiles, это примерно 30x быстрее чем просто читать с диска
  • Сделать и постоянно обновлять поисковый индекс ключ_поиска->file_offset, прямое решение - ассоциативный массив System.Collection.Generics Dictionary
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы