0

(见下面的更新)

从 C#.Net 应用程序(约 5 秒)中查询大约 500,000 行的非常简单的 Sqlite 数据表时,我遇到了查询性能缓慢的问题。

我使用 LinqPad 以及 2 个数据库浏览器(均基于 QtSql)在完全相同的数据库上尝试了完全相同的查询,它的运行速度提高了 10 倍(约 0.5 秒)。相同的查询,相同的数据库,不同的应用程序,只有我的运行速度不快。

无论我是返回值还是只是一个 Count(*),它的区别可以忽略不计。

我试过了:

  • 为每个 .Net 3.5/4/4.5 构建
  • 为每个 AnyCPU/x86/x64 构建
  • 使用 System.Data.Sqlite、sqlite-net 以及通过 COM 直接访问 sqlite3 dll
  • 为每个 WPF/WinForms 构建
  • 查询的不同变体

这些都不会对查询时间产生任何明显的影响。

我知道使用 JOIN 重写查询可能会有所帮助,但我无法弄清楚为什么相同的查询在 LinqPad/Sql 浏览器中运行良好,但在我尝试创建的任何应用程序中却没有。我一定错过了一些非常基本的东西。

示例表:

"CREATE TABLE items(id INTEGER PRIMARY KEY, id1 INTEGER, id2 INTEGER, value INTEGER)"

示例查询字符串(尽管基本上任何使用子查询的查询都需要很长时间):

SELECT count(*) 
FROM items WHERE 
id2 IN 
(
    SELECT DISTINCT id2 FROM items WHERE id1 IN 
    (
        SELECT DISTINCT id1 FROM items WHERE id2 = 100000 AND value = 10
    )
    AND value = 10
) 
AND value = 10 
GROUP BY id2

我知道这可能会使用 JOINS 和索引来重新编写以加快速度,但事实仍然是,此查询在其他应用程序中的运行速度要快得多。我在这里缺少什么,为什么无论我尝试什么,相同的查询都会运行得这么慢?

更新:似乎 sqlite 的版本与该问题有关。使用旧的 System.Data.Sqlite v1.0.66.0 查询就像其他应用程序一样运行,但是使用更新的版本很慢。我还没有确定具体在哪个版本发生了变化,但我很确定这与底层的 sqlite3 版本有关,而不是专门针对 System.Data.Sqlite。如果有人知道在这种情况下可能发生的变化会导致子查询速度变慢,或者如果有设置或某些东西可以使新版本的 sqlite 中的子查询运行得更快,请告诉我!

同样,该查询是一个示例,并不理想且部分冗余……问题更多是关于为什么它在一个而不是另一个中起作用。

提前感谢您提供任何额外的输入!

更新:已解决

请看下面我的回答。

4

3 回答 3

0

一些建议:

您说您不想重新处理查询或添加索引。这是显而易见的事情。如果没有任何索引,sqlite 必须至少扫描一次(或更可能多次)您的 500,000 行表。

根据您上面的查询,我将向列id1id2.

另一件事是您上面的查询似乎有点多余。也许你有你的理由,但我不明白为什么查询应该如此复杂。简化查询:

select count(*)
from items
where id2 = 100000 and value = 10

于 2013-02-11T15:03:38.093 回答
0

尝试

SELECT ID1.id2, count(*) 
FROM items ID2
JOIN items ID1
  on ID2.id2 = ID1.id1
 and ID1.id2 = 100000 
 and ID1.value = 10 
 and ID2.valu3 = 10
group by ID1.id2
于 2013-02-11T17:11:48.160 回答
0

好吧,事实证明这与 SQLite 1.7.0 引入的自动索引有关。在我的情况下,在这种没有索引的表上使用子查询意味着 SQLite 创建自动索引所花费的时间导致了查询所经历的额外开销。

解决方案是使用:

PRAGMA automatic_index=OFF;

在使用“IN”子句的任何查询的开头。

在列上创建索引也可以解决这个问题(未经测试),但是在这种特殊情况下,创建索引所需的额外大小/磁盘使用是不值得的。

这也表明我使用的 LinqPad SQLite 插件和数据库查看器基于旧的 sqlite 版本。

更多信息可以在以下位置找到:

http://www.sqlite.org/src/info/8011086c85c6c4040

http://www.sqlite.org/optoverview.html#autoindex

感谢所有回复的人。

于 2013-02-12T08:34:02.307 回答