2014-12-01 2 views
6

Как сохранить большие объемы данных, прочитав из файла CSV (скажем, 20 миллионов строк). До сих пор он близок к 1 1/2 дням и хранит всего 10 миллионов строк, как я могу это сделать, чтобы он стал быстрее, и есть возможность запускать это параллельно.Как сохранить большие объемы данных, прочитав из файла CSV

Я использую код здесь, чтобы прочитать CSV, я хотел бы знать, есть ли лучший способ достичь этого.

См: dealing with large CSV files (20G) in ruby

+0

Какова цель иметь 20-миллиметровые ряды в памяти? Почему бы просто не прочитать каждую строку и не вставить ее в базу данных SQLite?(тогда сделайте анализ там). Если вы пытаетесь выполнять функции большого количества данных, тогда вы захотите посмотреть на MapReduce. – Besto

+0

Я бы хотел обработать все данные и сохранить их в базе данных MySQL для дальнейшей обработки. Сообщите мне, могу ли я оптимизировать способ чтения данных или партии данных. Оцените все фрагменты кода здесь. Также прошли строки? – brisk

+0

Можете ли вы привести пример схемы? Тогда я соберу фрагмент. – Besto

ответ

4

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

Вероятно, для шинирования файл будет быстрее пользователю инструмент, как разделенного

split -l 1000000 ./test.txt ./out-files- 

Затем, когда вы обрабатываете каждого из файлов и предполагается, что вы вставляя записи вместо того, чтобы вставить их один за другим, вы могут комбинировать их в партии и делать объемные вставки. Что-то вроде:

INSERT INTO some_table 
VALUES 
(1,'data1'), 
(2, 'data2') 

Для повышения производительности вам нужно построить SQL Statement себя и выполнить его:

ActiveRecord::Base.connection.execute('INSERT INTO <whatever you have built>') 
+2

Кроме того, обязательно запустите все свои вставки в блоке 'ActiveRecord :: Base.transaction {}'. –

2

Поскольку вы хотели бы сохраняться ваши данные в MySQL для дальнейшей обработки, с использованием нагрузки Data Infile из MySQL будет быстрее. что-то вроде следующего с вашей схемой:

SQL = "LOAD DATA LOCAL INFILE 'big_data.csv' в таблице испытаний ПЛОЩАДКИ TERMINATED BY '' ПРИЛАГАЕМОЙ BY '\"' ЛИНИЙ TERMINATED BY '\ п' (Foo, foo1)»

CON = ActiveRecord :: Base.connection

con.execute (SQL)

+0

Добавить local_infile: true для database.yml согласно [link] (http://stackoverflow.com/questions/21256641/enabling-local-infile-for-loading-data-into-remote-mysql-from-rails) – Graham

1

Ключевые моменты:

  1. Если вы используете MySQL InnoDB engine, мой совет в том, что всегда определяет автоматический прирост PRIMARY KEY, InnoDB использует кластерный индекс для хранения данных в таблице. Кластеризованный индекс определяет физический порядок данных в таблице.
    относятся: http://www.ovaistariq.net/521/understanding-innodb-clustered-indexes/
  2. Config ваши параметры сервера MySQL, наиболее важными из них являются
    (1) закрыть MySQL Двоичный
    (2) innodb_buffer_pool_size.
    (3) innodb_flush_log_at_trx_commit
    (4) bulk_insert_buffer_size
    Вы можете прочитать: http://www.percona.com/blog/2013/09/20/innodb-performance-optimization-basics-updated/
  3. Вы должны использовать производитель-потребитель сценарий.

Извините за мой плохой английский.