如何优化针对 db2 数据库的 SQL/Python select 查询?
How to optimize SQL/Python select queries against a db2 database?
通过 Python 连接到服务器上的 db2 数据库并查询巨大的 table(可能有 200 密耳记录,50 列)。 table 用于分析(OLAP 可能是正确的术语)而不是事务。我想优化我的 sql/python 代码以加快查询执行速度。
在没有深入了解 sql 查询的情况下,我怀疑 SELECT
语句从 table 的第一条记录开始,并一直持续到满足查询为止。 FETCH FIRST 10 ROWS ONLY
在 <1 秒内执行。但是,包含 WHERE date_col > 20210701
需要扫描几条 100 密耳的记录,然后才能识别前 10 条记录——执行该查询需要几分钟以上的时间。通过游标对象的性能相似。
或者,我通过 Microsoft Access 连接到同一个 table。 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 不是整数也不是日期时间,而是 CHAR 格式。这导致了索引问题,导致查询缓慢。通过将结果放在引号中解决了问题:...WHERE date_col > '20210701'
而不是 ...WHERE date_col > 20210701
.
另一个问题是对 Access 处理数据的方式的误解。切换到“数据表视图”时,Access 不会执行整个查询。相反,它执行等同于 FETCH FIRST 50 ROWS ONLY
的操作。查询出现得如此之快是因为服务器不需要将整个数据集发送给客户端。但是,整个查询在导出时执行。在我的例子中,这大约需要 5 秒,并且相当于我正在执行的 Python 脚本的过程。
谢谢大家在上面的评论。
通过 Python 连接到服务器上的 db2 数据库并查询巨大的 table(可能有 200 密耳记录,50 列)。 table 用于分析(OLAP 可能是正确的术语)而不是事务。我想优化我的 sql/python 代码以加快查询执行速度。
在没有深入了解 sql 查询的情况下,我怀疑 SELECT
语句从 table 的第一条记录开始,并一直持续到满足查询为止。 FETCH FIRST 10 ROWS ONLY
在 <1 秒内执行。但是,包含 WHERE date_col > 20210701
需要扫描几条 100 密耳的记录,然后才能识别前 10 条记录——执行该查询需要几分钟以上的时间。通过游标对象的性能相似。
或者,我通过 Microsoft Access 连接到同一个 table。 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 不是整数也不是日期时间,而是 CHAR 格式。这导致了索引问题,导致查询缓慢。通过将结果放在引号中解决了问题:
...WHERE date_col > '20210701'
而不是...WHERE date_col > 20210701
.另一个问题是对 Access 处理数据的方式的误解。切换到“数据表视图”时,Access 不会执行整个查询。相反,它执行等同于
FETCH FIRST 50 ROWS ONLY
的操作。查询出现得如此之快是因为服务器不需要将整个数据集发送给客户端。但是,整个查询在导出时执行。在我的例子中,这大约需要 5 秒,并且相当于我正在执行的 Python 脚本的过程。
谢谢大家在上面的评论。