2015-08-24 7 views
2

У меня есть файл A, содержащий некоторые записи около 40Millon. У меня есть другой файл B, который содержит некоторые записи около 70Millon. Теперь мне нужно перебирать файл A для каждого поиска записей, если есть запись в файле B. Если это так, напишите запись в файле C.обработка огромных файлов несколько раз в JAVA

Просьба предложить идеи о том, как достичь этого, не набивая память и с минимальным временем , Я уже пробовал apache lucene, но у него были дополнительные накладные расходы на создание индекса, так как файл B с 70 миллионами записей будет меняться ежедневно (т. Е. Мы получаем этот файл из внешней системы), очень сложно перевосстанавливать индексы ежедневно

ответ

4

Потяните данные в mysql или postgres как таблицу. Интересующие поля индексируют и присоединяются.

2

Вы можете использовать хронику.

Вы можете загрузить 70 миллионов записей за несколько секунд до нескольких минут в зависимости от размера записей. Вы можете обновить записи в реальном времени, если вам нужно.

Как Хроника Карта сохраняется и от кучи вы можете сделать это вне линии или в другом процессе, если это поможет.

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

0

Предполагая, что у вас недостаточно памяти для загрузки данных и нет базы данных, удобной для индексирования, лучше всего использовать sort-merge join.

По сути, сортируйте оба файла по критериям соединения/поиска, затем прочитайте файлы параллельно («слияние»).

1

Если база данных не вариант, у меня есть идея:

Preprocess свой второй файл: захватить его и отсортировать его (в алфавитном порядке):

Anna 
Aqua 
Claire 
Jeremy 
Joseph 
Vill 

Теперь создать файл, который отображает каждый символ алфавита до номера строки, где он используется в качестве стартового символа имени:

A,0 
C,2 
J,3 
V,5 

Предыдущие шаги c alled preprocessing, и вы должны сделать это перед компиляцией своей программы. Очевидно, что сортировка такого огромного файла займет много времени, но при использовании этого метода ваша развернутая программа будет намного быстрее, если вы используете этот метод:

Когда вы повторяете свой первый файл, предположим, что вы найдете Joseph. То, что вы делаете, это захватить первый символ J, а затем использовать сопоставление для определения номера первой строки, который используется этим символом. Отображение даст 3, и поэтому вы будете перебирать второй файл на такой номер строки. Это экономит много времени, потому что вы сможете пропустить с помощью equals() по нескольким строкам, которые явно не соответствуют вашим критериям поиска. Чтобы найти Joseph, вам нужно будет только проверить на Jeremy, а затем Joseph.

Теперь, когда вы понимаете эту технику, вы можете сделать ее намного более эффективной, используя два уровня:: вместо каждого символа в алфавите создайте другое сопоставление для каждого символа алфавита.В случае J было бы

JE,3 
JO,4 

Поскольку вы ищете Joseph, вы легко определить, что номер строки, чтобы начать искать это четвертый один, таким образом, пропуская даже больше сравнений.

Вы можете сделать это на более уровнях: три, четыре и т. Д. Это зависит от вас, чтобы определить, какой из них наиболее оптимален в вашем случае. Сопоставления не занимают много места, и они сэкономят вам много времени, пропуская лишние записи.

Очевидным недостатком является то, что предварительная обработка файла с 70 миллионами записей является очень исчерпывающим - но это то, что вашим конечным пользователям не придется испытывать.

Это один из способов сделать это.

Примечание: Вам нужно будет повторить каждую строку второго файла, чтобы достичь нужного номера строки. Дело в том, что вам не нужно выполнять какие-либо сравнения, и вы увидите, что это позволит вам сэкономить много времени на обработку.

Смежные вопросы