Wydaje się, że „problemem” była konwersja typu, która występuje z typu dziesiętnego MySQL na dziesiętny pythona. Dziesiętny, który MySQLdb, pymysql i pyodbc robią na danych. Zmieniając plik converters.py (w ostatnich wierszach) w MySQLdb, aby:
conversions[FIELD_TYPE.DECIMAL] = float
conversions[FIELD_TYPE.NEWDECIMAL] = float
zamiast dziesiętnego. Decimal wydaje się całkowicie rozwiązać problem, a teraz następujący kod:
import MySQLdb
import numpy
import time
t = time.time()
conn = MySQLdb.connect(host='',...)
curs = conn.cursor()
curs.execute("select x,y from TABLENAME")
data = numpy.array(curs.fetchall(),dtype=float)
print(time.time()-t)
Działa w mniej niż sekundę! Co zabawne, dziesiętny. Dziesiętny nigdy nie wydawał się być problemem w profilerze.
Podobne rozwiązanie powinno działać w pakiecie pymysql. pyodbc jest trudniejszy:wszystko jest napisane w C++, dlatego musiałbyś przekompilować cały pakiet.
AKTUALIZUJ
Oto rozwiązanie, które nie wymaga modyfikacji kodu źródłowego MySQLdb:Python MySQLdb zwraca datetime.date i dziesiętny Rozwiązaniem jest ładowanie danych liczbowych do pand:
import MySQLdb
import pandas.io.sql as psql
from MySQLdb.converters import conversions
from MySQLdb.constants import FIELD_TYPE
conversions[FIELD_TYPE.DECIMAL] = float
conversions[FIELD_TYPE.NEWDECIMAL] = float
conn = MySQLdb.connect(host='',user='',passwd='',db='')
sql = "select * from NUMERICTABLE"
df = psql.read_frame(sql, conn)
Pokonuje MATLAB o współczynnik ~4 podczas ładowania tabeli 200k x 9!