pandas读取sql查询和读取sql表的区别
Posted
技术标签:
【中文标题】pandas读取sql查询和读取sql表的区别【英文标题】:difference between pandas read sql query and read sql table 【发布时间】:2018-06-18 16:33:44 【问题描述】:这两个命令在执行时间上是否有区别:
import pandas as pd
df=pd.read_sql_query('SELECT * FROM TABLE',conn)
df=pd.read_sql_table(TABLE, conn)
感谢您的帮助
【问题讨论】:
我无法让pd.read_sql()
和 pd.read_sql_query()
使用 postgres 架构,使用 d6tstack.utils.pd_readsql_query_from_sqlengine()
【参考方案1】:
我认为你不会注意到这种差异。
这是两个函数的源代码:
In [398]: pd.read_sql_query??
Signature: pd.read_sql_query(sql, con, index_col=None, coerce_float=True, params=None, parse_dates=None, chunksize=None)
Source:
def read_sql_query(sql, con, index_col=None, coerce_float=True, params=None,
parse_dates=None, chunksize=None):
pandas_sql = pandasSQL_builder(con)
return pandas_sql.read_query(
sql, index_col=index_col, params=params, coerce_float=coerce_float,
parse_dates=parse_dates, chunksize=chunksize)
和
In [399]: pd.read_sql_table??
Signature: pd.read_sql_table(table_name, con, schema=None, index_col=None, coerce_float=True, parse_dates=None, columns=None, chunksize=None
)
Source:
def read_sql_table(table_name, con, schema=None, index_col=None,
coerce_float=True, parse_dates=None, columns=None,
chunksize=None):
con = _engine_builder(con)
if not _is_sqlalchemy_connectable(con):
raise NotImplementedError("read_sql_table only supported for "
"SQLAlchemy connectable.")
import sqlalchemy
from sqlalchemy.schema import MetaData
meta = MetaData(con, schema=schema)
try:
meta.reflect(only=[table_name], views=True)
except sqlalchemy.exc.InvalidRequestError:
raise ValueError("Table %s not found" % table_name)
pandas_sql = SQLDatabase(con, meta=meta)
table = pandas_sql.read_table(
table_name, index_col=index_col, coerce_float=coerce_float,
parse_dates=parse_dates, columns=columns, chunksize=chunksize)
if table is not None:
return table
else:
raise ValueError("Table %s not found" % table_name, con)
注意:我故意切断了文档字符串...
【讨论】:
好的,那么推荐哪一个? @NoName,使用最适合你的那个 ;)【参考方案2】:主要区别很明显,与df=pd.read_sql_query('SELECT * FROM TABLE',conn)
您使用的 sql 查询可能很复杂,因此执行会非常耗时/耗费资源。使用
df=pd.read_sql_table(TABLE, conn)
您下载一个表并仅指定列、架构等。
【讨论】:
【参考方案3】:在 read_sql_query 中,您可以添加 where 子句,您可以添加连接等,这样可以减少从数据库移动到数据框中的数据量。如果您有一个巨大的表并且只需要少量的行,那就更好了。
另一方面,如果您的表很小,请使用 read_sql_table 并在 python 中操作数据框。它比 SQL 更灵活。
【讨论】:
【参考方案4】:我尝试了无数次,尽管我在上面阅读过,但我不同意大部分过程或结论。
过程
如果要比较两种方法,添加厚层SQLAlchemy
或pandasSQL_builder
(即pandas.io.sql.pandasSQL_builder
,没有import
)和其他类似的非独立 片段至少可以说没有帮助。在没有 noise 的情况下比较两种方法的唯一方法是尽可能干净地使用它们,并且至少在相似的情况下使用它们。
假设
关于假设有一种说法......在假设差异不明显和对pd.read_sql_query
提出无用的考虑之间,这一点变得非常模糊。这里唯一的明显考虑是,如果有人比较pd.read_sql_query
和pd.read_sql_table
,那就是桌子,整张桌子,只有桌子。调用where
、join
等只是浪费时间。
此外,该问题明确要求 read_sql_table
和 read_sql_query
与 SELECT * FROM table
之间的区别。
我的代码
我在 SQLite、MariaDB 和 PostgreSQL 上一遍又一遍地运行它。我专门使用SQLAlchemy
来创建引擎,因为pandas
需要这个。数据来自coffee-quality-database,我将所有三个引擎中的文件data/arabica_data_cleaned.csv
预加载到名为coffee
的数据库中的一个名为arabica
的表中
这是我的脚本的摘要版本:
import time
import pandas as pd
from sqlalchemy import create_engine
sqlite_engine = create_engine('sqlite:///coffee.db', echo=False)
mariadb_engine = create_engine('mariadb+mariadbconnector://root:admin@127.0.0.1:3306/coffee')
postgres_engine = create_engine('postgresql://postgres:admin@127.0.0.1:5432/coffee')
for engine in [sqlite_engine, mariadb_engine, postgres_engine]:
print(engine)
print('\tpd.read_sql_query:')
startTime = time.time()
for i in range(100):
pd.read_sql_query('SELECT * FROM arabica;', engine)
print(f"\t[-- TIME --] time.time()-startTime:.2f sec\n")
print('\tpd.read_sql_table:')
startTime = time.time()
for i in range(100):
pd.read_sql_table('arabica', engine)
print(f"\t[-- TIME --] time.time()-startTime:.2f sec\n")
版本是:
Python:3.9.0 熊猫:1.2.4 SQLAlchemy:1.4.13 时间:内置我的结果
这是一个示例输出:
Engine(sqlite:///coffee.db)
pd.read_sql_query:
[-- TIME --] 2.58 sec
pd.read_sql_table:
[-- TIME --] 3.60 sec
Engine(mariadb+mariadbconnector://root:***@127.0.0.1:3306/coffee)
pd.read_sql_query:
[-- TIME --] 2.84 sec
pd.read_sql_table:
[-- TIME --] 4.15 sec
Engine(postgresql://postgres:***@127.0.0.1:5432/coffee)
pd.read_sql_query:
[-- TIME --] 2.18 sec
pd.read_sql_table:
[-- TIME --] 4.01 sec
结论
以上是一个示例输出,但我一遍又一遍地运行它,唯一的观察是在每一次运行中,pd.read_sql_table
总是 比pd.read_sql_query
花费更长的时间。这听起来很违反直觉,但这就是为什么我们在向这里倾注知识之前实际隔离问题并测试。
我没有机会对结果进行适当的统计分析,但乍一看,我会冒着风险说差异很大,因为两个“列”(query
和 table
计时)回到近距离(从一个跑到另一个跑)并且都相当远。在某些运行中,table
在某些引擎上花费的时间是其两倍。
如果/当我有机会进行这样的分析时,我会用结果和matplotlib
证据来补充这个答案。
上下文
我最初的想法是在表达到数千列时调查 SQL 与 MongoDB 的适用性。 pdmongo.read_mongo
(来自pdmongo
包)破坏了pd.read_sql_table
——它对大型表的性能非常差——但达不到pd.read_sql_query
。
在大约 900 列中,pd.read_sql_query
的性能比 pd.read_sql_table
高 5 到 10 倍!
【讨论】:
以上是关于pandas读取sql查询和读取sql表的区别的主要内容,如果未能解决你的问题,请参考以下文章