Utwórz bazę danych MySQL z jedną tabelą, która ma jedno pole. Następnie zaimportuj plik do bazy danych. Ułatwi to wyszukiwanie określonej linii.
Nie sądzę, żeby cokolwiek innego mogło być szybsze (jeśli head
i tail
już zawodzi). W końcu aplikacja, która chce znaleźć linię, n
musi przeszukiwać cały plik, dopóki nie znajdzie n
nowych linii. Bez pewnego rodzaju wyszukiwania (przesunięcie indeksu linii do bajtu w pliku) nie można osiągnąć lepszej wydajności.
Biorąc pod uwagę, jak łatwo jest utworzyć bazę danych MySQL i zaimportować do niej dane, wydaje mi się, że jest to realne podejście.
Oto jak to zrobić:
DROP DATABASE IF EXISTS helperDb;
CREATE DATABASE `helperDb`;
CREATE TABLE `helperDb`.`helperTable`( `lineIndex` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, `lineContent` MEDIUMTEXT , PRIMARY KEY (`lineIndex`) );
LOAD DATA INFILE '/tmp/my_large_file' INTO TABLE helperDb.helperTable (lineContent);
SELECT lineContent FROM helperTable WHERE ( lineIndex > 45000000 AND lineIndex < 45000100 );
/tmp/my_large_file
byłby plikiem, który chcesz przeczytać.
Prawidłowa składnia do importowania pliku z wartościami rozdzielanymi tabulatorami w każdym wierszu to:
LOAD DATA INFILE '/tmp/my_large_file' INTO TABLE helperDb.helperTable FIELDS TERMINATED BY '\n' (lineContent);
Kolejną ważną zaletą tego jest to, że jeśli później zdecydujesz się wyodrębnić inny zestaw wierszy, nie musisz czekać godzin ponownie na przetwarzanie (chyba że oczywiście usuniesz bazę danych).