SQL Server - 规避大型IN(...)子句的最佳实践(> 40000项)

时间:2014-01-27 09:16:50

标签: c# sql-server

我正在开发一个分析用户上传的Excel文件的ASP.NET应用程序。这些文件包含有关客户的各种数据(一行=一位客户),关键字段为CustomerCode。基本上,数据以DataTable对象的形式出现。

在某些时候,我需要从SQL获取有关指定客户的信息,并将其与上传的用户进行比较。我是按照以下方式做的:

  1. CustomerCode'Customer1','Customer2',...'CustomerN'列制作逗号分隔的客户列表。
  2. 将此字符串传递给SQL查询IN (...)子句并执行它。
  3. 这是正常的,直到我尝试在The query processor ran out of internal resources and could not produce a query plan子句中传递~40000个项目时遇到IN (...)异常。

    琐碎的方式似乎是:

    1. IN (...)替换为查询模板中的= 'SomeCustomerCode'
    2. 为每个CustomerCode执行此查询40000次。
    3. 执行DataTable.Merge 40000次。
    4. 有没有更好的方法解决这个问题?

      注意:我无法执行IN (SELECT CustomerCode FROM ... WHERE SomeConditions),因为数据来自Excel文件,因此无法从数据库中查询。

2 个答案:

答案 0 :(得分:1)

"Table valued parameters"值得研究,它允许你传入(通常通过C#端的DataTable多行 - 缺点是你需要正式声明并命名数据形状首先是SQL服务器。

但是,您可以使用SqlBulkCopy将行放入临时表,然后只将JOIN放到该表中。如果你有并行调用者,你需要在行上使用某种会话标识符来区分并发使用(并且:不要忘记之后删除会话的数据)。

答案 1 :(得分:0)

由于您提到的错误,您不应该一次处理太多记录,并且它是如此大的批次,它需要花费太多时间来运行并且您不能并行执行任何操作。您不应该一次只处理1条记录,因为那时SQL服务器通信的开销太大了。选择中间的东西,例如。一次10000条记录。您甚至可以并行化处理,在处理上一个10000批次时,您可以在后台开始运行下一个10000的SQL。