iCa*_*arp 8 c# sqlite datatable performance loading
我需要根据关键字获取一些数据,查询测试到100%准确,但问题是加载reader
速度很慢.我试过用一个完全不包含inner join
s的查询替换这个查询,并且加载非常快.所以我想知道,因为我只选择了一列,为什么DataTable.Load()花了这么多时间?这是不是SQLite
的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();
Run Code Online (Sandbox Code Playgroud)
SQLite 查询规划器提供了一些有关 SQLite 查询优化的提示。
一些可能适用于您的问题的项目:
1.) 由于 SQLite 中的实现,您可能会尝试重新排序多个连接:
SQLite 当前的实现仅使用循环连接。也就是说,连接是作为嵌套循环实现的。连接中嵌套循环的默认顺序是 FROM 子句中最左边的表形成外循环,最右边的表形成内循环。
因此,根据 JOIN 的构造方式,性能可能会有所不同。
SQLite 尝试自动优化这一点,但据我了解文档,并不能保证成功(我强调):
但是,SQLite 将以不同的顺序嵌套循环,如果这样做有助于选择更好的索引。[...] 连接重新排序是自动的,并且通常工作得足够好,程序员不必考虑它,特别是在使用 ANALYZE 来收集有关可用索引的统计信息的情况下。但有时需要程序员的一些提示。
2.) 另外,请注意 INNER JOINS 在内部转换为 WHERE 子句,因此文档 WHERE 部分中的任何性能提示也可能适用:
在上面第 1.0 段中描述的 WHERE 子句分析之前,内连接的 ON 和 USING 子句被转换为 WHERE 子句的附加项。因此,对于 SQLite,使用较新的 SQL92 连接语法相对于较旧的 SQL89 逗号连接语法没有计算优势。他们最终在内连接上完成了完全相同的事情。
3.) 如果列上有任何索引,您可能会考虑在语句中选择更多列:
为了使用该索引,索引的每一列都不需要出现在 WHERE 子句术语中。但所使用的索引列中不能有间隙。