【发布时间】:2021-08-06 14:11:13
【问题描述】:
通过 Python 连接到服务器上的 db2 数据库并查询一个巨大的表(可能有 200 万条记录,50 列)。此表用于分析(OLAP 可能是正确的术语)而不是事务。我想优化我的 sql/python 代码以更快地执行查询。
没有深入了解sql查询,我的怀疑是SELECT语句从表的第一条记录开始,一直持续到满足查询为止。 FETCH FIRST 10 ROWS ONLY 在 WHERE date_col > 20210701 需要在识别前 10 条记录之前扫描几条 1 亿条记录——执行此查询需要几分钟以上的时间。通过游标对象的性能类似。
或者,我通过 Microsoft Access 连接到同一个表。 Access 中相同的日期查询在 <.5>SELECT 语句还要快。 Access 肯定在幕后做着我不知道的事情。
所以Access证明了这些sql查询可以快速执行的概念。我留下了一个问题:如何优化我的 sql/python 代码以匹配 Microsoft Access 的性能?谢谢大家。
import ibm_db_dbi as db
import pandas as pd
cnxn = db.connect(dsn= '********',
user= '********',
password='********',
host= '********',
database='********')
cols = "{0}col1, {0}col2, {0}col3, {0}col4".format('database.')
# Executes in <1 second
fast_sql = '''SELECT {} FROM bigtable
FETCH FIRST 10 ROWS ONLY'''.format(cols)
# Executes in ~5 seconds
slower_sql = '''SELECT {} FROM bigtable
WHERE col1 = 1234
FETCH FIRST 10 ROWS ONLY'''.format(cols)
# Giving up after ~3 minutes
slowest_sql = '''SELECT {} FROM bigtable
WHERE date_col > 20210701
FETCH FIRST 10 ROWS ONLY'''.format(cols)
df = pd.read_sql_query(horribly_slow_sql , cnxn)
cnxn.close()
【问题讨论】:
-
您需要查看在每种情况下实际发送到数据库服务器的查询。另外,您如何衡量执行时间?
-
任何索引?有关表设计的任何信息? date_col 是什么类型?从一些性能基础开始,即在可重现的环境中收集事实。
-
“mil”是指几百万还是几千?
-
@mustaccio 如何找到从 Microsoft Access 发送到数据库的实际 sql?到目前为止,谷歌没有帮助。有什么想法吗?
-
@data_henrik 感谢您的回复。通过访问探索“对象定义”属性表明有 7 个索引。不过它们有点神秘,所以我不确定它们实际上是如何传递到 Access 的 sql 查询中的。不过,这是一个很好的起点。