这两个命令在执行时间方面有区别吗:
import pandas as pd
df=pd.read_sql_query('SELECT * FROM TABLE',conn)
df=pd.read_sql_table(TABLE, conn)
谢谢你的帮助。我尝试了无数次,尽管我读到的内容中有很多过程和结论,但我不同意其中大部分。
如果您要比较两种方法,添加厚重的SQLAlchemy
或pandasSQL_builder
(即pandas.io.sql.pandasSQL_builder
,甚至没有一个import
)和其他非独立的片段毫无帮助。唯一在没有噪音 的情况下比较两种方法的方法是尽可能干净地使用它们,并且至少在类似的情况下。
关于假设有句话... 在假设差异不明显与提出无用的考虑pd.read_sql_query
之间,这个问题就会严重模糊。唯一的明显的考虑是,如果任何人正在比较pd.read_sql_query
和pd.read_sql_table
,那就是表格,整个表格,而非其他。调用where
、join
等只是浪费时间。
此外,该问题明确要求区分使用SELECT * FROM table
的read_sql_table
和read_sql_query
之间的区别。
我在SQLite、MariaDB和PostgreSQL上反复运行了这个代码。我仅使用SQLAlchemy
创建引擎,因为pandas
需要这样。数据来自coffee-quality-database,我在所有三个引擎中预加载了文件data/arabica_data_cleaned.csv
到名为arabica
的表中,在名为coffee
的数据库中。
以下是我的脚本的概述:
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")
版本如下:
这是一个样本输出:
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
对于某些引擎需要的时间是query
所需时间的两倍。
如果有机会运行这样的分析,我将用结果和matplotlib
证据补充这个答案。
我的初衷是调查表达数千列数据时 SQL 与 MongoDB 的适用性。来自pdmongo
包的pdmongo.read_mongo
使pd.read_sql_table
相形见绌——后者对于大型表格的性能表现非常差,但它仍不及pd.read_sql_query
。
在大约 900 列的情况下,pd.read_sql_query
的表现比 pd.read_sql_table
快 5 至 10 倍!
read_sql_query("SELECT * FROM table")
大约花费了100秒read_sql_table(table_name)
大约花费了200秒我认为你不会注意到这个差别。
以下是两个函数的源代码:
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)
注意:我故意删掉了文档字符串...
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()。 - citynorman