Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 数据表读取器加载非常慢_C#_Performance_Sqlite_Datatable_Loading - Fatal编程技术网

C# 数据表读取器加载非常慢

C# 数据表读取器加载非常慢,c#,performance,sqlite,datatable,loading,C#,Performance,Sqlite,Datatable,Loading,我需要根据关键字获取一些数据,查询被测试为100%准确,但问题是阅读器的加载速度非常慢。我尝试用一个根本不包含内部连接的查询替换这个查询,加载速度非常快。所以我想知道,既然我只选择了一列作为结果,为什么DataTable.Load()要花费这么多时间?是否是SQLite的ExecuteReader加载了整个结果而不仅仅是一列 在使用DataTable之前,执行每个reader.Read()的平均时间为7秒 这是我的代码: _database.Connect(); var selectComman

我需要根据关键字获取一些数据,查询被测试为100%准确,但问题是
阅读器的加载速度非常慢。我尝试用一个根本不包含
内部连接的查询替换这个查询,加载速度非常快。所以我想知道,既然我只选择了一列作为结果,为什么DataTable.Load()要花费这么多时间?是否是SQLite的
ExecuteReader
加载了整个结果而不仅仅是一列

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

这是我的代码:

_database.Connect();
var selectCommand=new SQLiteCommand(
@“从MD中选择A.ID作为我的\u ID
MD.ID上的内部连接TMD=TMD.ID\U MD
TR.ID上的内部连接TR=TMD.ID\u TR
P.ID上的内部连接P=TR.ID\u P
DP.ID上的内部连接DP\U P=P.ID
CD上的内部连接CD.ID=DP.ID\U CD
其中CD.DESC=@DESC”
);
选择Command.Parameters.AddWithValue(“@desc”,value);
使用(DbDataReader=\u database.ExecuteQuery(selectCommand))
{
DataTable数据=新的DataTable(“MyData”);
数据加载(读卡器);
}
_database.Disconnect();

我认为这是由于SQLite的特性和大量的连接造成的

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

提供了一些有关SQLite查询优化的提示

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

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

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

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

SQLite试图自动对此进行优化,但据我所知,文档中没有成功的保证(我重点介绍):

但是,如果这样做,SQLite将以不同的顺序嵌套循环 将有助于它选择更好的指数。 [...] 连接重新排序是自动的,通常工作得很好,程序员可以 不必考虑它,尤其是如果使用ANALYZE来收集 有关可用索引的统计信息但偶尔会从 需要程序员。

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

内部联接的ON子句和USING子句转换为 WHERE子句分析之前WHERE子句的附加条款 如上文第1.0段所述。因此,对于SQLite,没有 使用较新的SQL92连接语法比 旧的SQL89逗号连接语法。他们最终都完全完成了任务 在内部联接上也是这样

如果有任何索引,你可以考虑在你的语句中选择更多的列:

索引的每一列都不必出现在WHERE中 子句术语,以便使用该索引。但是,不可能 所用索引列中的空白。


听起来你的查询很慢。有没有一种不同的方式访问你的表,这样你就不必做这么多的连接?我知道这会很痛苦。。不幸的是,我们需要根据其中一个字段连接这两个表。考虑到当前数据库架构,这些连接是它们之间的唯一连接。什么是
\u数据库
,为什么有
连接
断开
之类的方法?不要重新发明轮子。您还应该为您的连接使用
using语句
,以确保它尽快“关闭”。这是像ASP.NET这样的多线程环境吗?我更新了答案。我们为每个线程使用1个DB实例,并在需要时使用事务。这个问题不会出现在任何其他查询中,只会出现在这个查询中。@Souvlaki:可能有表锁。连接池是否已启用(
pooling=True
)?如果出现异常,您也不会关闭连接,请使用
using
try/catch/finally
。“SQLite的性质”是否意味着预期结果与当前返回的结果不同?@Souvlaki:我的意思是,SQLite不支持如此多的连接的良好负载,此外,您可能有一个大文件,这会降低生成的永久性。即使在Navicat上查询速度非常快,我认为您是正确的。SQLiteCommand.ExecuteReader()是一个瓶颈。所有连接都是建立在主键上的,我认为这解决了索引问题,但我真的在考虑1+2是否可以成为我的案例的救命稻草。我在执行sql命令之前使用了
ANALYZE
,查询执行得非常快。因此,考虑到您为这个特定问题提供了正确的方向,您就得到了答案。谢谢