C# Linq2Sql是否通过多个ID选择记录?
例如,我有一个包含10000000条记录的表和内存中包含100000个ID的列表 如何通过这些ID选择所有记录? 显然,我可以这样做:C# Linq2Sql是否通过多个ID选择记录?,c#,linq-to-sql,C#,Linq To Sql,例如,我有一个包含10000000条记录的表和内存中包含100000个ID的列表 如何通过这些ID选择所有记录? 显然,我可以这样做: var ids = GetIds(); var result = from q in ctx.Records where ids.Contains(q.Id) select q; SELECT * FROM Records WHERE id IN (/*one hundreds of thousand goe
var ids = GetIds();
var result = from q in ctx.Records
where ids.Contains(q.Id)
select q;
SELECT * FROM Records WHERE id IN (/*one hundreds of thousand goes here O_O*/)
但如果我这样做,会有两个问题:
- 每次使用此查询时生成的SQL中都会出现异常
- O(N)每行的复杂性。所以,我将在几年后收到我的成绩
linq2sql
是如何做到这一点的,还是无法绕过
更新
- GetIds-此函数返回大约100.000个ID。不,我不能加入它它是计算出来的
- 是的,我测试了它,调试了它,看到了生成的内容。是这样的:
var ids = GetIds(); var result = from q in ctx.Records where ids.Contains(q.Id) select q;
简单数学:10.000.000 x 100.000将给出1.000.000.000.000的时间复杂度。这是极不有效的SELECT * FROM Records WHERE id IN (/*one hundreds of thousand goes here O_O*/)
var ids = GetIds();
//Insert all ids into database (bulk insert)
var result = from q in ctx.Records
join i in ctx.Ids on q.Id equals i.Id
select q;
这样,操作将在数据库中进行,您将克服in
子句中项目数量的限制
记录的id
字段应该有一个索引(或者如果它是主键,它也已经被索引)
新Ids
表的id字段也应该被索引
这样,联接将是一个散列联接
,而不是一个嵌套联接
——相当于.Net解决方案,该解决方案将ID
集合用作散列集
,而不是列表
最后,要并行支持许多操作,您可以使用带有两列的Id
,OperationId
。OperationId
将提供给特定插入的所有Id
s,然后您的查询将如下所示:
var result = from q in ctx.Records
join i in ctx.Ids on q.Id equals i.Id
where i.OperationId = _the operationId given by the insert_
select q;
_确保操作Id
也已编制索引-可以是Id
的相同索引,但请确保它是顺序中的第一个索引
根据DBMS的不同,您也可以将您的表作为一个临时表
——至少对于Oracle来说,它存储了每个连接会话的数据——因此您可以一次从多个会话中插入数据,但数据不是共享的——因此您不需要操作ID
什么让您认为它是O(N)对于每一行,什么是getid
?这是从哪里来的?返回类型是什么?您测试过它的速度慢吗?它将被转换为,其中ID位于(1,2,3,4,5,…,100000)
查询中。当然,这不是最好的方法(因此,您可以使用用户定义的表类型和表值参数,但不再使用LINQ To SQL)。将GetIds()
填充到临时表中(或者@Tim建议的表值参数),并对其进行连接或查询。@eocron06-GetIds
从何处获取这些ID?