我们知道,在sql中使用IN让我们的where子句可以规定多个值。当需要从一个集合中查询包含某几个值的记录的时候,通常我们会选择使用IN来实现,其实,使用JOIN也可以实现这样的功能,而且性能要比IN好。我会从以下几个方面来进行总结。

  1. 使用IN和JOIN的性能对比
  2. EF中如何使用JOIN来代替IN

使用IN和JOIN的性能对比

  首先来看一段sql语句,然后通过执行计划来比较它们之间的性能。

使用IN和JOIN查询的代码:

下面是它们的执行计划:

通过执行计划,可以看到使用JOIN的性能要比IN好。

EF中如何使用JOIN来代替IN

  我们在使用EF的时候, 会有很多像下面这样的查询。

 List<int> productIds = new List<int>
{
,,,,,,,,,,,,,,,
};
using (var db = new PackageFHContext())
{
var containerResult = db.ProductMasterSet.Where(p => productIds.Contains(p.ProductID));
}

实际上,这种写法生成的sql代码就是使用了IN,下面是使用Sql Server Profiler监测到的结果。

SELECT …..
FROM [dbo].[Pkg_ProductMaster] AS [Extent1]
WHERE [Extent1].[ProductID] IN (15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30);

那么,我们怎样来实现JOIN来代替IN呢,我们可以借助SQL CLR函数来实现,代码如下。

 List<int> productIds = new List<int>
{
,,,,,,,,,,,,,,,
};
using (var db = new PackageFHContext())
{
var joinResult = from p in db.ProductMasterSet
join c in db.CLR_Split(string.Join(",", productIds), ",", true) on p.ProductID.ToString() equals c.id
select p;
}

这里使用了SQL CLR的Split函数将list处理成一个表后再关联过滤的,生成的SQL语句如下。

Select ……
FROM [dbo].[Pkg_ProductMaster] AS [Extent1]
INNER JOIN [dbo].[CLR_Split](@input, @delimiter, @isRemoveEmptyEntries) AS [Extent2] ON CAST( [Extent1].[ProductID] AS nvarchar(max)) = [Extent2].[id]
WHERE 58 = [Extent1].[DepartureCityID];

使用Join代替In的更多相关文章

  1. SQL Server-聚焦IN VS EXISTS VS JOIN性能分析(十九)

    前言 本节我们开始讲讲这一系列性能比较的终极篇IN VS EXISTS VS JOIN的性能分析,前面系列有人一直在说场景不够,这里我们结合查询索引列.非索引列.查询小表.查询大表来综合分析,简短的内 ...

  2. SQL Server-聚焦NOT IN VS NOT EXISTS VS LEFT JOIN...IS NULL性能分析(十八)

    前言 本节我们来综合比较NOT IN VS NOT EXISTS VS LEFT JOIN...IS NULL的性能,简短的内容,深入的理解,Always to review the basics. ...

  3. Nested Loops join时显示no join predicate原因分析以及解决办法

    本文出处:http://www.cnblogs.com/wy123/p/6238844.html 最近遇到一个存储过程在某些特殊的情况下,效率极其低效, 至于底下到什么程度我现在都没有一个确切的数据, ...

  4. c# Enumerable中Aggregate和Join的使用

    参考页面: http://www.yuanjiaocheng.net/ASPNET-CORE/asp.net-core-environment.html http://www.yuanjiaochen ...

  5. 超详细mysql left join,right join,inner join用法分析

    下面是例子分析表A记录如下: aID        aNum 1           a20050111 2           a20050112 3           a20050113 4   ...

  6. join Linq

    List<Publisher> Publishers = new List<Publisher>(); Publisher publish1 = new Publisher() ...

  7. mysql join 和left join 对于索引的问题

    今天遇到一个left join优化的问题,搞了一下午,中间查了不少资料,对MySQL的查询计划还有查询优化有了更进一步的了解,做一个简单的记录: select c.* from hotel_info_ ...

  8. BCL中String.Join的实现

    在开发中,有时候会遇到需要把一个List对象中的某个字段用一个分隔符拼成一个字符串的情况.比如在SQL语句的in条件中,我们通常需要把List<int>这样的对象转换为“1,2,3”这样的 ...

  9. [数据库基础]——图解JOIN

    阅读导航 一.概要 二.JOIN分类 三.JOIN分类详解 一.概要 JOIN对于接触过数据库的人,这个词都不陌生,而且很多人很清楚各种JOIN,还有很多人对这个理解也不是很透彻,这次就说说JOIN操 ...

  10. Spark join 源码跟读记录

    PairRDDFunctions类提供了以下两个join接口,只提供一个参数,不指定分区函数时默认使用HashPartitioner;提供numPartitions参数时,其内部的分区函数是HashP ...

随机推荐

  1. 泛型IComparer<T>排序

    class Program { static void Main(string[] args) { GetListTest(); } private static void GetListTest() ...

  2. iOS - UIAlertView

    前言 NS_CLASS_DEPRECATED_IOS(2_0, 9_0, "UIAlertView is deprecated. Use UIAlertController with a p ...

  3. Git 的origin和master分析 push/diff/head(转)

    1.origin/master : 一个叫 origin 的远程库的 master 分支 2.HEAD指向当前工作的branch,master不一定指向当前工作的branch 3.git  push ...

  4. Struts1 标签库 说明

    Struts提供了五个标签库,即:HTML.Bean.Logic.Template和Nested. HTML标签 : 用来创建能够和Struts 框架和其他相应的HTML 标签交互的HTML 输入表单 ...

  5. Python中的join()函数split()函数

    函数:string.join() Python中有join()和os.path.join()两个函数,具体作用如下:     join():    连接字符串数组.将字符串.元组.列表中的元素以指定的 ...

  6. lmdb存储的一些库相关函数

    MDB_env 为一个结构体,Opaque structure for a database environment. MDB_txn :Opaque structure for a transact ...

  7. oracle对象类型

    Oracle的对象类型 对象类型 在PL/SQL中,面向对象的程序设计师基于对象类型来完成的.对象类型是用户自定义的一种复合数据类型,它封装了数据结构和用于操纵这些数据结构的过程和函数. 数据库的对象 ...

  8. mysql 建立索引场合及索引使用

    索引建立场合: ① where后边字段 适合建立索引 ② order by 排序字段适合建立索引 ③ 索引覆盖 即 所要查询的字段本身就是索引 直接在索引中查询数据. 例如 select name,a ...

  9. 探索 Pexpect,第 1 部分:剖析 Pexpect

    Pexpect 是一个用来启动子程序并对其进行自动控制的 Python 模块. Pexpect 可以用来和像 ssh.ftp.passwd.telnet 等命令行程序进行自动交互.本文章介绍 Pexp ...

  10. python的变量传递

    python中变量都被视为对象的引用.python函数调用传递参数的时候,不允许程序员选择传值还是传引用,python参数传递采用的都是“传对象引用”的方式.     这种方式相当于传值和传引用的结合 ...