別のオプションは、multiprocessing
を使用することです。 モジュール、クエリを分割して複数の並列プロセスに送信し、結果を連結します。
pandas
についてあまり知らなくても チャンク化-チャンク化は手動で行う必要があると思います(データによって異なります)... LIMIT/OFFSETを使用しないでください-パフォーマンスはひどいものになります。
データによっては、これは良い考えではないかもしれません。クエリを分割する便利な方法がある場合(たとえば、時系列の場合、または使用する適切なインデックス列がある場合は、それが理にかなっている可能性があります)。さまざまなケースを示すために、以下に2つの例を示します。
例1
import pandas as pd
import MySQLdb
def worker(y):
#where y is value in an indexed column, e.g. a category
connection = MySQLdb.connect(user='xxx', password='xxx', database='xxx', host='xxx')
query = "SELECT * FROM example_table WHERE col_x = {0}".format(y)
return pd.read_sql(query, connection)
p = multiprocessing.Pool(processes=10)
#(or however many process you want to allocate)
data = p.map(worker, [y for y in col_x_categories])
#assuming there is a reasonable number of categories in an indexed col_x
p.close()
results = pd.concat(data)
例2
import pandas as pd
import MySQLdb
import datetime
def worker(a,b):
#where a and b are timestamps
connection = MySQLdb.connect(user='xxx', password='xxx', database='xxx', host='xxx')
query = "SELECT * FROM example_table WHERE x >= {0} AND x < {1}".format(a,b)
return pd.read_sql(query, connection)
p = multiprocessing.Pool(processes=10)
#(or however many process you want to allocate)
date_range = pd.date_range(start=d1, end=d2, freq="A-JAN")
# this arbitrary here, and will depend on your data /knowing your data before hand (ie. d1, d2 and an appropriate freq to use)
date_pairs = list(zip(date_range, date_range[1:]))
data = p.map(worker, date_pairs)
p.close()
results = pd.concat(data)
おそらくこれを行うためのより良い方法(そして適切にテストされていないなど)。試してみるとどうなるか興味があります。