【问题标题】:difference between pandas read sql query and read sql tablepandas读取sql查询和读取sql表的区别
【发布时间】: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)

感谢您的帮助

【问题讨论】:

标签: python sql pandas dataframe sqlite


【解决方案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 倍!

      【讨论】:

        猜你喜欢
        • 2017-07-26
        • 1970-01-01
        • 2021-10-07
        • 1970-01-01
        • 2015-03-02
        • 1970-01-01
        • 2023-03-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多