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】:

我尝试了无数次,尽管我在上面阅读过,但我不同意大部分过程或结论。

过程

如果要比较两种方法,添加厚层SQLAlchemypandasSQL_builder(即pandas.io.sql.pandasSQL_builder,没有import)和其他类似的非独立 片段至少可以说没有帮助。在没有 noise 的情况下比较两种方法的唯一方法是尽可能干净地使用它们,并且至少在相似的情况下使用它们。

假设

关于假设有一种说法......在假设差异不明显和对pd.read_sql_query 提出无用的考虑之间,这一点变得非常模糊。这里唯一的明显考虑是,如果有人比较pd.read_sql_querypd.read_sql_table,那就是桌子,整张桌子,只有桌子。调用wherejoin 等只是浪费时间。

此外,该问题明确要求 read_sql_tableread_sql_querySELECT * 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 花费更长的时间。这听起来很违反直觉,但这就是为什么我们在向这里倾注知识之前实际隔离问题并测试

我没有机会对结果进行适当的统计分析,但乍一看,我会冒着风险说差异很大,因为两个“列”(querytable 计时)回到近距离(从一个跑到另一个跑)并且都相当远。在某些运行中,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表的区别的主要内容,如果未能解决你的问题,请参考以下文章

pandas把读取sql的结果写入到excel文件

从表中随机选择行 - Python Pandas 读取 SQL

数据处理,Pandas vs SQL 你会选择哪一个?

mysql sql 语句

读取mysql数据库

ExecuteNonQuery,ExecuteReader,ExecuteScalar 区别