【问题标题】:InnerJoin vs Contains, which is faster内连接与包含,哪个更快
【发布时间】:2015-09-18 10:54:07
【问题描述】:

我正在编写查询以使用 linq 从数据库中查找整数值的总和。在开发过程中,我有两个想法。我可以通过包含或内部连接来做到这一点。以下是查询

var Customer = db.tbl_User_to_CustomerMast.Where(i => i.fk_Store_ID == s.ShopID).ToList();

查询1:

var RewardCount = db.tbl_RewardAwardMast.Where(i => Customer.Select(j => j.User_Customer_ID).ToList().Contains(i.fk_Customer_UserID.Value)).Sum(i => i.RewardPoints).GetValueOrDefault(0);

查询 2:

var RewardCount = Customer.Join(db.tbl_RewardAwardMast, i => i.User_Customer_ID, j => j.fk_Customer_UserID, (i, j) => new { Customer = i, Reward = j }).Sum(i=>i.Reward.RewardPoints).GetValueOrDefault(0);

我知道在这两个查询中,计算都将在服务器端完成以匹配记录。

那么哪个查询适合更快的执行呢?

【问题讨论】:

  • 你为什么不分析你的代码来找出答案?将这两个查询重复 100 万次,并测量每种情况下的总执行时间。
  • 你的意思是我应该把这两个查询都放在 for 循环中以进行大量重复?它会给我正确的结果吗?我以前从未尝试过
  • 我建议你也看一下生成的 SQL——它可能完全一样。这与在 LINQ to Objects 中做同样的事情会有很大的不同。
  • 是的,使用一个简单的for循环并使用the Stopwatch class来测量执行时间。

标签: c# sql linq


【解决方案1】:

我会说查询 1 会更快,因为它会被翻译成类似这样的简单 SQL:

SELECT SUM(RewardPoints)
FROM User_to_CustomerMast
WHERE fk_Customer_UserID IN (c1,c2,c3,c4,c5,...,cx)

查询 2 可能会更慢,因为您实际上是在尝试将本地列表变量与数据库中的数据连接起来。这个列表最初来自 DB 无关紧要,在执行ToList() 时会丢失与 DB 的关联。要执行这样的查询,必要的信息将被传递给 DB 以生成第二个表,因此JOIN 现有表有一些东西。这将使用 UNION 完成。

SELECT SUM(RewardPoints)
FROM 
    User_to_CustomerMast INNER JOIN
    (
         SELECT c1
         UNION 
         SELECT c2
         UNION 
         SELECT c3
         UNION 
         SELECT c4
         UNION 
         SELECT c5
         UNION 
         ...
         ...
         SELECT cx
     ) AS T ON T.Id = fk_Customer_UserID 

如您所见,当本地列表增长时,查询会快速扩展。如果您的列表太长,有时您甚至可能会遇到 SQL 太复杂的异常。

您可以在此处查看有关此主题的详细分析: http://blog.hompus.nl/2010/08/26/joining-an-iqueryable-with-an-ienumerable/

【讨论】:

    猜你喜欢
    • 2012-11-11
    • 1970-01-01
    • 2018-05-23
    • 2013-09-29
    • 2010-10-09
    • 2014-12-04
    相关资源
    最近更新 更多