"Проблемът" изглежда е бил преобразуването на типа, което се случва от десетичния тип на MySQL в десетичния тип на python. Decimal, който MySQLdb, pymysql и pyodbc правят върху данните. Чрез промяна на файла converters.py (в последните редове) в MySQLdb да има:
conversions[FIELD_TYPE.DECIMAL] = float
conversions[FIELD_TYPE.NEWDECIMAL] = float
вместо decimal.Decimal изглежда напълно решава проблема и сега следният код:
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)
Изпълнява се за по-малко от секунда! Какво е смешно, десетичният. Изглежда, че десетичният никога не е бил проблемът в профайлъра.
Подобно решение трябва да работи в пакета pymysql. pyodbc е по-сложен:всичко е написано на C++, следователно ще трябва да прекомпилирате целия пакет.
АКТУАЛИЗИРАНЕ
Ето решение, което не изисква промяна на изходния код на MySQLdb:Python MySQLdb връща datetime.date и decimal След това решението за зареждане на цифрови данни в pandas:
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)
Побеждава MATLAB с фактор ~4 при зареждане на таблица 200k x 9!