2012-07-10 210 views
8

我需要根据关键字获取一些数据,该查询被测试为100%准确,但问题是reader的加载速度很慢。我试图用一个不包含inner join的查询替换这个查询,并且加载非常快。所以我想知道,因为我只选择一列作为结果,为什么DataTable.Load()需要这么多时间?加载整个结果的是SQLiteExecuteReader而不仅仅是一列吗?DataTable读取器加载速度很慢

在使用DataTable之前,执行每个reader.Read()的平均时间为7秒。

这是我的代码:

_database.Connect(); 

var selectCommand = new SQLiteCommand(
@"SELECT A.ID AS MY_ID FROM MD 
INNER JOIN TMD ON MD.ID = TMD.ID_MD 
INNER JOIN TR ON TR.ID = TMD.ID_TR 
INNER JOIN P ON P.ID = TR.ID_P 
INNER JOIN DP ON DP.ID_P = P.ID 
INNER JOIN CD ON CD.ID = DP.ID_CD 
WHERE CD.DESC = @desc" 
); 

selectCommand.Parameters.AddWithValue("@desc", value); 

using (DbDataReader reader = _database.ExecuteQuery(selectCommand)) 
{ 
    DataTable data = new DataTable("MyData"); 
    data.Load(reader); 
} 
_database.Disconnect(); 
+1

这听起来像你的查询是简单的。有没有不同的方式来访问你的表,这样你就不必做很多连接了? – Tejs 2012-07-10 13:53:34

+0

我知道这会伤人..不幸的是,我们需要根据其中一个字段连接2个表格。鉴于当前的数据库架构,这些连接是它们之间的唯一连接。 – iCantSeeSharp 2012-07-10 13:55:25

+0

什么是_database,为什么它有像Connect和Disconnect这样的方法?不要重新发明轮子。您还应该为连接使用'using-statement',以确保它尽快“关闭”。这是像ASP.NET这样的多线程环境吗? – 2012-07-10 13:55:55

回答

2

The SQLite Query Planner提供了关于SQLite查询优化的一些提示。

可能适用于你的问题的一些项目:

1)由于SQLite的执行你可以尝试重新排列多个联接:

当前实现的SQLite只使用循环连接。也就是说, 说,联接被实现为嵌套循环。 嵌套循环在链接中的默认顺序是FROM子句中最左边的表格至 形成外部循环,最右边的表格形成内部循环。

所以,根据JOIN的构造方式,可能会有性能差异。

的SQLite试图自动优化这一点,但据我了解的文档有成功不能保证(由我亮点):

然而,SQLite的将鸟巢,如果在做不同的顺序循环所以 将帮助它选择更好的指数。 [...] 加入重新排序是自动的,通常运行良好,程序员 不必考虑它,特别是如果ANALYZE已被用于收集有关可用索引的统计信息 。 但是偶尔需要 程序员的一些提示。

2)另外,请注意,内部连接在内部转换为WHERE子句,因此任何在表现技巧在文档的部分可能适用,太:

的ON和内部联接的USING子句在上述段落1.0中的WHERE子句分析 之前被转换为WHERE子句的附加项。因此,对于SQLite,没有 计算优势,可以使用较早的SQL89连接语法而不是较旧的SQL89逗号连接语法。他们最终都在内部连接上完成了相同的事情,完成了 。

3)你可能会考虑在你的语句来选择多个列,如果上面有任何索引:

这是没有必要为索引的每列出现在WHERE 为了使用该索引,使用子句术语。但是不能是 使用的索引列中的间隔。

+0

所有连接都建立在主键上,我认为这解决了索引的问题,但我真的想要考虑1 + 2是否可以成为我的案例的救星。 – iCantSeeSharp 2012-07-10 14:31:00

+0

我在我的sql命令之前使用了'ANALYZE',查询执行得非常快。所以,考虑到你为这个特定问题提供了正确的方向,你会得到答案。谢谢! – iCantSeeSharp 2012-07-10 14:53:03

3

我认为出现这种情况的SQLite由于性质和大量的联接。

尝试重构数据库方案,如使数据非规范化以加快访问速度。

+0

“SQLite的性质”是否意味着预期结果与当前返回的不同? – iCantSeeSharp 2012-07-10 13:56:21

+0

@Souvlaki:我的意思是说,SQLite不支持这么多的连接的良好加载,也可能有一个大文件会降低最终的持久性。 – abatishchev 2012-07-10 13:58:55

+0

尽管Navicat的查询速度相当快? – iCantSeeSharp 2012-07-10 14:03:33