8

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

在使用 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();
4

2 回答 2

3

我认为这是由于 SQLite 的性质和大量的连接而发生的。

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

于 2012-07-10T13:54:35.300 回答
2

SQLite 查询计划器提供了一些关于 SQLite 查询优化的提示。

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

1.) 由于 SQLite 中的实现,您可能会尝试重新排序多个连接:

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

因此,根据 JOIN 的构造方式,性能可能会有所不同。

SQLite 尝试自动优化它,但据我了解文档并不能保证成功(我强调):

但是,如果这样做有助于选择更好的索引,SQLite 将以不同的顺序嵌套循环。[...] 连接重新排序是自动的,通常工作得很好,程序员不必考虑它,特别是如果 ANALYZE 已用于收集有关可用索引的统计信息。但有时需要程序员的一些提示。

2.) 另外,请注意 INNER JOINS 在内部转换为 WHERE 子句,因此文档的 WHERE 部分中的任何性能提示也可能适用:

内部连接的 ON 和 USING 子句在上面 1.0 段中描述的 WHERE 子句分析之前转换为 WHERE 子句的附加术语。因此,对于 SQLite,使用较旧的 SQL89 逗号连接语法相比,使用较新的 SQL92 连接语法没有计算优势。他们最终都在内部连接上完成了完全相同的事情。

3.)您可以考虑在语句中选择更多列,如果它们上有任何索引:

为了使用该索引,索引的每一列都不必出现在 WHERE 子句术语中。但所使用的索引列中不能有间隙。

于 2012-07-10T14:27:00.883 回答