Python中的Sqlite3模块远比Shell更慢

rwo*_*lst 6 python sql sqlite shell

我在Python中使用sqlite3模块,但是相对于在命令shell中运行sqlite3中的查询,我发现某个SELECT查询的速度非常慢.我将首先说两个版本都是相同的3.7.17.

我的疑问是

SELECT r.ID, r.Date FROM my_table r
WHERE
r.Date IN (SELECT Date FROM my_table WHERE ID = r.ID GROUP BY Date LIMIT 2);
Run Code Online (Sandbox Code Playgroud)

Python代码是

con = lite.connect(path_to_database)
cur = con.cursor()

with con:
    cur.execute(sql_query)
Run Code Online (Sandbox Code Playgroud)

where sql_query是包含初始查询的字符串变量.

我假设问题在于优化IN子查询.

性能细节:my_table包含167000条记录,shell中的查询需要大约10秒,Python中的查询需要大于5分钟(当它到达这一点时我停止了它).

目前,因为它是表创建我只是将代码复制并粘贴到shell中作为一种解决方法,我该如何解决这个问题,以便我可以从Python运行查询?

加成

当我跑步时,EXPLAIN QUERY PLAN我得到以下内容

贝壳:

0           0           0           SCAN TABLE PIT_10_Days AS r (~500000 rows)
0           0           0           EXECUTE CORRELATED LIST SUBQUERY 1
1           0           0           SEARCH TABLE PIT_10_Days USING AUTOMATIC C
1           0           0           USE TEMP B-TREE FOR GROUP BY
Run Code Online (Sandbox Code Playgroud)

蟒蛇:

0           0           TABLE PIT_10_Days AS r 
0           0           TABLE PIT_10_Days
Run Code Online (Sandbox Code Playgroud)

我不确定EXPLAIN QUERY PLAN在使用Python时是否存在差异,或者它实际上是问题本身.

swe*_*zel 1

很抱歉这么晚了,但我现在才发现这个问题。
不幸的是,我不知道为什么 sqlite3 模块的行为与 shell 不同,但您可以尝试从一开始就避免相关查询。我不确定它是否总是执行您想要的操作,因为您没有对子查询中的结果进行排序。

我想您想要每个 ID 的两个最新日期?尝试这个:

SELECT r.ID AS ID, max( r.Date ) AS Date
 FROM my_table AS r
 GROUP BY r.ID

UNION

SELECT r.ID, max( r.Date )
  FROM 
      my_table AS r
      JOIN ( 
        SELECT ID,
               max( Date ) AS Date
          FROM my_table
         GROUP BY ID) AS maxDat
      ON
      r.ID = maxDat.ID AND
      r.Date != maxDat.Date
 GROUP BY r.ID;
Run Code Online (Sandbox Code Playgroud)

它选择 ID 及其最新日期。然后,它将这个结果与表中的类似选择相结合,其中取出实际的最新日期,以便您获得第二个最新日期。如果您需要超过最新的两个日期,这将变得相当麻烦,但对于仅两个日期,它应该没问题,而且可能要快得多。