SQLite sqlite3_step() 因大数据库而挂起

标签 sql database sqlite subquery

我正在编写一个小型 Objective-C 库,它可以与嵌入式 SQLite 数据库配合使用。

我使用的 SQLite 版本是 3.7.13(使用 SELECT sqlite_version() 检查)

我的查询是:

SELECT ROUND(AVG(difference), 5) as distance 
FROM (
  SELECT (
    SELECT A.timestamp - B.timestamp 
    FROM ExampleTable as B 
    WHERE B.timestamp = (
      SELECT MAX(timestamp) 
      FROM ExampleTable as C 
      WHERE C.timestamp < A.timestamp
    )
  ) as difference 
  FROM ExampleTable as A 
  ORDER BY timestamp)

基本上它输出按时间戳排序的行之间的平均时间戳差异。

我在一个包含 35k 行的示例数据库上尝试了查询,它的运行时间约为 100 毫秒。到目前为止一切顺利。

然后,我在另一个包含 100k 行的示例数据库上尝试查询,它卡在 sqlite3_step() 处,占用了 100% 的 CPU 使用率。

由于我无法使用调试器进入sqlite3_step(),是否有其他方法可以让我了解函数挂起的位置或这里出现问题的调试日志?

我还尝试在 100k 行数据库上运行我的库中的其他查询,没有问题,但这些都是没有子查询的简单查询,这也是事实。也许这就是问题所在?

谢谢

更新

这是按要求的EXPLAIN QUERY PLAN 的输出:

"1","0","0","SCAN TABLE ExampleTable AS A"
"1","0","0","EXECUTE CORRELATED SCALAR SUBQUERY 2"
"2","0","0","SCAN TABLE ExampleTable AS B"
"2","0","0","EXECUTE CORRELATED SCALAR SUBQUERY 3"
"3","0","0","SEARCH TABLE ExampleTable AS C"
"1","0","0","USE TEMP B-TREE FOR ORDER BY"
"0","0","0","SCAN SUBQUERY 1"

最佳答案

可以使用此列上的索引来优化按时间戳值查找行:

CREATE INDEX whatever ON ExampleTable(timestamp);

而且这个查询效率很低:ORDER BY 不会影响求平均值的值,并且 BC 中的 timestamp 值始终是相同,因此您可以删除其中之一:

SELECT ROUND(AVG(difference), 5) AS distance 
FROM (
  SELECT timestamp -
         (SELECT MAX(timestamp)
          FROM ExampleTable AS B
          WHERE timestamp < A.timestamp)
         AS difference
  FROM ExampleTable AS A)

关于SQLite sqlite3_step() 因大数据库而挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27770455/

相关文章:

php - mysql/php 中的撇号

android - Android 中的 onUpgrade() sqlite 数据库

ruby-on-rails - 设置 Rhodes 环境并已安装 Ruby on Rails

php - 1 表查询 vs 连接多表查询性能

sql - 在 Oracle 中创建前导零

mysql - JOIN 查询太慢了。不会用INDEX?

java - SQL postgres - 如何在连接后重命名每列,因为它们的字段太多

c# - Entity Framework DbSet<TEntity>.Where(e => true) 性能

mysql - 内连接和全外连接查询

python - 在数据库中插入和读取数据