【发布时间】:2013-02-07 10:46:25
【问题描述】:
我有一个在包含 5,00,000 多条记录的数据表上运行的 LINQ 查询。此查询仅返回一行,但运行几乎需要 30 秒。这是我的查询
var callDetailsForNodes = from records in dtRowForNode.Select().Select(dr =>
new
{
caller1 = StringComparer.CurrentCultureIgnoreCase.Compare(dr["F1"], dr["F2"]) < 0 ? dr["F1"] : dr["F2"],
caller2 = StringComparer.CurrentCultureIgnoreCase.Compare(dr["F1"], dr["F2"]) < 0 ? dr["F2"] : dr["F1"],
time = dr["F3"],
filters = dr.Field<string>("F9")
}).Where(dr => (dtMin <= Convert.ToDateTime(dr.time)) && (dtMax >= Convert.ToDateTime(dr.time)) && (lstCallType.Contains(dr.filters))
&& (dtMinTime <= Convert.ToDateTime(dr.time).TimeOfDay) && (dtMaxTime >= Convert.ToDateTime(dr.time).TimeOfDay))
.GroupBy(drg => new { drg.caller1, drg.caller2 })
.Select(drg => new { drg.Key.caller1, drg.Key.caller2, count = drg.Count() }).AsEnumerable()
where (records.caller1.ToString() == VerSelected || records.caller2.ToString() == VerSelected)
select records;
我再次运行查询以重新排列从上述查询中获取的数据
var callDetailsForNodes_ReArrange = from records in callDetailsForNodes.Select(r => new
{
caller1 = r.caller1.ToString() == VerSelected ? r.caller1 : r.caller2,
caller2 = r.caller1.ToString() != VerSelected ? r.caller1 : r.caller2,
count = r.count
})
select records;
然后我只是将此集合绑定到gridview。 有没有什么有效的方法来查询这么大的数据集
编辑
我尝试逐步调试程序,发现这两个查询实际上运行得很快,并且在我将此查询的结果集添加到 ObservableCollection 以将其绑定到 gridview 的步骤中花费了时间。这是代码
foreach (var callDetailsForNode_ReArrange in callDetailsForNodes_ReArrange)
{
_CallForNodes.Add(new CallForNodeData
{
Caller1 = callDetailsForNode_ReArrange.caller1.ToString(),
Caller2 = callDetailsForNode_ReArrange.caller2.ToString(),
Count = callDetailsForNode_ReArrange.count
});
}
这里 callDetailsForNodes_ReArrange 的结果集计数 = 1
【问题讨论】:
-
" 有没有什么有效的方法可以查询这么大的数据集" 是的,使用数据库!
-
您是否已分解查询以查看最慢的部分?例如。您可以在您的第一个
Select之后停下来并致电ToList()。然后添加Where并调用ToList()等。这将帮助您识别导致最慢的部分。然而,正如 Tim 所说,这应该在数据库中完成。 -
我怀疑您可能会感到困惑。一旦你开始迭代集合,它就会执行你的查询。
callDetailsForNodes只是一个查询,直到您导致它执行为止。将 1 项添加到ObservableCollection应该不会很慢。
标签: c# performance linq