2013-02-11 37 views
0

(見下更新)查詢使用大約慢10倍使用System.Data.SQLite的較新版本的SQLite數據庫子查詢/ sqlite3.dll

我查詢時非常具有緩慢的查詢性能問題在C#.Net應用程序(約5秒)內,大約有500,000行的Sqlite數據表可以簡化。

我已經嘗試完全相同的查詢在完全相同的數據庫上使用LinqPad,以及2數據庫瀏覽器(都基於QtSql),它運行速度快10倍(〜0.5secs)。相同的查詢,相同的數據庫,不同的應用程序,只有我的運行速度不快。

無論我是返回值還是計數(*),它都會產生微不足道的差異。

我已經試過:

  • 建設每個.NET爲每個AnyCPU/86/64
  • 的3.5/4/4.5
  • 建築使用每個System.Data.Sqlite的時,SQLite網,以及經由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 

我知道這也許可以重新編寫使用的連接和索引來加速它,但事實是這個查詢的工作速度明顯快於其他應用程序。我在這裏錯過了爲什麼相同的查詢運行速度如此之慢,無論我嘗試什麼?

更新:似乎sqlite的版本有問題。使用傳統的System.Data.Sqlite v1.0.66.0,查詢就像其他應用程序一樣運行,但使用更新的版本很慢。我沒有明確指出這個版本究竟改變了什麼版本,但我很確定這是針對底層的sqlite3版本而不是System.Data.Sqlite的。如果有人知道在這種情況下可能會導致子查詢變慢的原因,或者如果有設置或某些事情可以使子查詢在新版本的sqlite中運行得更快,請讓我知道!

同樣,查詢是一個例子,並不理想,部分冗餘......問題更多地是關於它爲什麼在一個而不是另一箇中起作用。

在此先感謝您的任何其他意見!

UPDATE:解決

見我的回答如下。

+0

單獨計數(*)與一組是沒有意義的。你確定這是來自LinqPad的相同查詢嗎? – Paparazzi 2013-02-11 16:55:53

+0

感謝Blam,你說得對,使用的示例查詢實際上是原始的修剪版本,但仍產生所述的結果。查詢在所有測試中都與此相同。 – user2061270 2013-02-12 02:38:41

回答

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

感謝大家作出答覆。

0

一些建議:

你說你不想重做你的查詢,也不需要添加索引。這是在這裏做的明顯的事情。沒有任何索引,sqlite必須至少掃描一次500,000行表(或多次)。

根據上面的查詢,我將索引添加到列id1id2

另一件事是您的上面的查詢似乎有點多餘。也許你有你的理由,但我不明白爲什麼查詢應該如此複雜。簡化查詢:

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

+0

再次查看該查詢更復雜。 id2 FROM items WHERE id1 IN – Paparazzi 2013-02-11 17:07:17

+0

@Blam - argh,我現在看到它。我知道這太容易了! – 2013-02-11 17:26:05

+0

感謝您的輸入,我將索引和優化查詢,但這裏的問題也是爲什麼同樣的查詢具有如此不同的性能。 – user2061270 2013-02-12 02:44:41

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 
+0

此查詢似乎沒有工作。雖然我會記住查詢方法,如果手頭的問題無法解決。 – user2061270 2013-02-12 02:40:17