2015-07-29 3 views
6

У меня есть 5 миллионов строк в БД MySQL, сидящих над локальной сетью (так быстрое подключение, а не в Интернете).Загрузка 5 миллионов строк в Pandas из MySQL

Подключение к БД работает отлично, но если я пытаюсь сделать

f = pd.read_sql_query('SELECT * FROM mytable', engine, index_col = 'ID') 

Это занимает действительно долгое время. Даже чередование с chunksize будет медленным. Кроме того, я действительно не знаю, просто ли это там, или действительно получить информацию.

Я хотел бы спросить, для тех людей, которые работают с большими данными в БД, как они извлекают свои данные для своей сессии Pandas?

Было бы «умнее», например, выполнить запрос, вернуть файл csv с результатами и загрузить , что в Pandas? Звучит гораздо более активно, чем нужно.

+1

Не извлекайте 5 миллионов записей, особенно для широкого стола, I/O убьет вас. – dbugger

+1

@ dbugger: Да, извините, запрос есть только пример, я не 'SELECT * FROM table', но все же, если я куском, создание итератора для относительно небольшого подмножества записей (> 10%) никогда не будет end ... Поэтому я думаю, что я делаю что-то неправильно с рабочим процессом. Благодарю. –

+1

Просто убедитесь, что нет ничего плохого (кроме размера), если вы добавите 'LIMIT 100' (или больше) в запрос, он работает так, как ожидалось? – joris

ответ

3

Лучший способ загрузки все данных из таблицы из базы данных -любой-SQL в панд:

  1. сбросы данных из базы данных с помощью COPY для PostgreSQL, SELECT INTO OUTFILE для MySQL или аналогичного для других диалектов.
  2. Чтение файла CSV с пандами с помощью the pandas.read_csv function

Используйте разъем только для чтения несколько строк. Силой базы данных SQL является ее способность доставлять мелкие куски данных на основе индексов.

Доставка целых столов - это то, что вы делаете с отвалами.

+0

Если вы не хотите делать это вручную, посмотрите на 'odo': http://odo.readthedocs.org/en/latest/sql.html#conversions – joris

2

У меня была аналогичная проблема, работая с Oracle db (для меня выяснилось, что потребовалось много времени, чтобы получить все данные, в течение которых я понятия не имел, насколько далеко это было или была ли какая-либо проблема продолжалось) - мое решение состояло в том, чтобы передать результаты моего запроса в набор файлов csv, а затем загрузить их в Pandas.

Я уверен, что есть более быстрые способы сделать это, но это на удивление хорошо работало для наборов данных размером около 8 миллионов строк.

Вы можете увидеть код, я использовал на моей странице Github для easy_query.py, но функция ядра я выглядела так:

def SQLCurtoCSV (sqlstring, connstring, filename, chunksize): 
    connection = ora.connect(connstring) 
    cursor = connection.cursor() 
    params = [] 
    cursor.execute(sqlstring, params) 
    cursor.arraysize = 256 
    r=[] 
    c=0 
    i=0 
    for row in cursor: 
     c=c+1 
     r.append(row) 
     if c >= chunksize: 
      c = 0 
      i=i+1 
      df = pd.DataFrame.from_records(r) 
      df.columns = [rec[0] for rec in cursor.description] 
      df.to_csv(filename.replace('%%',str(i)), sep='|') 
      df = None 
      r = [] 
    if i==0: 
     df = pd.DataFrame.from_records(r) 
     df.columns = [rec[0] for rec in cursor.description] 
     df.to_csv(filename.replace('%%',str(i)), sep='|') 
     df = None 
     r = [] 

импортирует окружающий модуль cx_Oracle, чтобы обеспечить различные крюки базы данных/API-вызовы, но я ожидаю, что там будут аналогичные функции, доступные с помощью аналогичного MySQL MySQL.

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

Это также означает, что вы можете работать с исходными файлами, пока остальные извлекаются.

После того, как все данные будут сохранены в отдельных файлах, их можно будет загрузить в один кадр данных Pandas, используя несколько pandas.read_csv и pandas.concat операторов.

+0

Вы сравнили это с использованием' pd.read_sql_query '? Поскольку эта функция делает в основном то же самое (вызов 'execute'', а затем' fetchmany' (если используется chunksize)), я бы подумал, что 'read_sql_query' проще в использовании и даже быстрее. – joris

+0

Я должен сказать «нет», но не мог, но в зависимости от того, как он управляет параметром chunckize, похоже, что это может быть решением. Q: Как он обрабатывает параметр chunksize? например Скажем, мой запрос вернет 5 миллионов строк, а chunksize - 100 000, каков будет результат? Я никогда не понимал, как работает chunksize. –

+0

[позже отредактировано] Просто нашел [это] (http://stackoverflow.com/questions/15555005/get-inferred-dataframe-types-iteratively-using-chunksize), который предполагает, что существует какой-то объект chunking, который позволяет выполнять ступенчатые просмотры базовый набор данных - так что да, может быть, просто вещь. –

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