mir*_*han 9 c# linq entity-framework entity-framework-6
我有一个大型数据集,我需要在其中的一部分执行复杂的计算.对于我的计算,我需要根据输入参数从大型集合中获取一大块有序数据.
我的方法签名如下所示:
double Process(Entity e, DateTimeOffset? start, DateTimeOffset? end)
Run Code Online (Sandbox Code Playgroud)
我想到以下两种方法:
double result = 0d;
IEnumerable<Quote> items = from item in e.Items
where (!start.HasValue || item.Date >= start.Value)
&& (!end.HasValue || item.Date <= end.Value)
orderby item.Date ascending
select item;
...
return result;
Run Code Online (Sandbox Code Playgroud)
double result = 0d;
IEnumerable<Item> items = e.Items.OrderBy(i => i.Date);
if (start.HasValue)
items = items.SkipWhile(i => i.Date < start.Value);
if (end.HasValue)
items = items.TakeWhile(i => i.Date <= end.Value);
...
return result;
Run Code Online (Sandbox Code Playgroud)
如果我只是把它放在一起,我可能只是采用方法1,但是我的数据集的大小和数据集集的大小都太大而不能忽略轻微的效率损失,并且它至关重要得到的可枚举是有序的.
哪种方法会产生更有效的查询?我还有待考虑采用更有效的方法吗?
所提出的任何解决方案都可以安全地假设表格已被很好地索引.
SkipWhile不支持转换为 SQL。你需要放弃这个选项。
解决此问题的最佳方法是在用于范围选择的字段上创建索引,然后发出可 SARGable 的查询。where date >= start && date < end是 SARGable 并且可以使用索引。
!start.HasValue ||这不是一个好主意,因为这会破坏 SARGability。构建查询以便不需要这样做。例如:
if(start != null) query = query.Where(...);
Run Code Online (Sandbox Code Playgroud)
进行索引覆盖,您将获得最佳性能。没有任何额外的行需要处理。