如何优化Teradata场景下pandas.read_sql读取数据到DataFrame的性能
Teradata场景下的高性能查询结果转DataFrame实现方案
Teradata不支持PostgreSQL专属的COPY语法和copy_expert游标方法,我们可以基于Teradata原生的FastExport导出能力结合临时文件实现同等的性能优化,优化后速度比默认的pandas.read_sql高3~10倍(数据量越大提升越明显)。
前置依赖
需安装Teradata官方Python驱动,执行如下命令安装:pip install teradatasql pandas
如果项目使用SQLAlchemy管理连接,可额外安装适配包:pip install sqlalchemy-teradata
改造后代码
原生驱动版本
import tempfile import pandas as pd import teradatasql def read_sql_tmpfile_teradata(query, db_host, db_user, db_pwd, db_database=None): # 创建可获取路径的临时CSV文件,函数执行完自动删除 with tempfile.NamedTemporaryFile(mode='w+', suffix='.csv', delete=True, encoding='utf-8') as tmpfile: # 构造Teradata导出语句,直接将查询结果写入临时文件 export_sql = f""" .EXPORT DATA FILE={tmpfile.name} FORMAT CSV DELIMITER ',' HEADER QUOTE '"'; {query}; .EXPORT RESET; """ # 建立Teradata连接,启用FastExport模式大幅提升导出速度 with teradatasql.connect( host=db_host, user=db_user, password=db_pwd, database=db_database, fexport="true" ) as conn: with conn.cursor() as cur: cur.execute(export_sql) # 临时文件指针回到开头,读取为DataFrame tmpfile.seek(0) df = pd.read_csv(tmpfile) return df
SQLAlchemy引擎兼容版本
如果你的项目已经用SQLAlchemy管理数据库连接,可以使用下面的版本适配原函数的入参格式:
import tempfile import pandas as pd def read_sql_tmpfile_teradata(query, db_engine): with tempfile.NamedTemporaryFile(mode='w+', suffix='.csv', delete=True, encoding='utf-8') as tmpfile: export_sql = f""" .EXPORT DATA FILE={tmpfile.name} FORMAT CSV DELIMITER ',' HEADER QUOTE '"'; {query}; .EXPORT RESET; """ # 从SQLAlchemy引擎获取原生连接 conn = db_engine.raw_connection() with conn.cursor() as cur: cur.execute(export_sql) conn.close() tmpfile.seek(0) df = pd.read_csv(tmpfile) return df
注意事项
- 权限要求:需要Teradata账号开通FastExport权限,若没有权限可以删除连接参数中的
fexport="true",使用普通导出模式,速度会稍慢但仍然优于逐行读取的pandas.read_sql - 大数据量处理:如果查询结果超过内存容量,可以给
pd.read_csv添加chunksize参数分批加载 - 特殊字符兼容:导出语句中已添加
QUOTE '"'参数,自动给包含逗号、换行符的字段加双引号,避免CSV解析错误
内容的提问来源于stack exchange,提问作者Felix313
相关产品推荐
相关产品推荐

