优化 Python MySQL/连接器速度

agi*_*iap 5 python mysql csv pandas

我在 MySQL 中有一个表,其中包含以下列:

id int(11)
contract_id int(11)
datetime datetime
open decimal(18, 10)
high decimal(18, 10)
low decimal(18, 10)
close decimal(18, 10)
Run Code Online (Sandbox Code Playgroud)

该表相当大(> 3 亿行),但在数据库中进行的查询即使返回 300,000 行,也会在半秒内执行。但是,当我从 Python 检索数据时,它非常慢(相同的请求从 MySQL Workbench 中的 0.5 秒变为 Python 中的 34 秒):

import pandas as pd
import mysql.connector 

con = mysql.connector.connect(**CONFIG) 
cur = con.cursor()

def get_data1():
    df = pd.read_sql(
        """
        SELECT datetime, open, high, low, close 
        FROM prices
        WHERE contract_id = 1 
            AND datetime >= '2015-01-01 09:00:00' 
            AND datetime <= '2015-10-15 16:00:00'; 
        """, con)
    return df
Run Code Online (Sandbox Code Playgroud)

我发现将数据从 MySQL 导出到平面文件,然后在 Python 中读取它比直接查询数据库快 23 倍:

def get_data2():
    cur.execute(
        """
        SELECT datetime, open, high, low, close 
        FROM prices
        WHERE contract_id = 1 
            AND datetime >= '2015-01-01 09:00:00' 
            AND datetime <= '2015-10-15 16:00:00'
        INTO OUTFILE 'C:/Data/Temp.csv'
        FIELDS TERMINATED BY ','
        ENCLOSED BY '"'
        LINES TERMINATED BY "\n";
        """)
    return pd.read_csv('C:/Data/Temp.csv')
Run Code Online (Sandbox Code Playgroud)

怎么会这样?我怀疑这与数据类型转换有关。知道如何使函数get_data1更快而不必先导出到 CSV 吗?谢谢你。

agi*_*iap 3

以下解决方案比最初的解决方案快 3 倍(12 秒与 34 秒):

import mysql.connector
con = mysql.connector.connect(**CONFIG)
cur = con.cursor()
class MySQLConverter(mysql.connector.conversion.MySQLConverter):
    def _DECIMAL_to_python(self, value, desc=None):
        return float(value)
    _NEWDECIMAL_to_python = _DECIMAL_to_python

con.set_converter_class(MySQLConverter)
Run Code Online (Sandbox Code Playgroud)

它将MySQL十进制类型转换为Python float而不是decimal.Decimal,这样速度更快。仍然比需要 1.57s 完成的“CSV 解决方案”慢很多。还在挖...