我们知道,在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. 【T-SQL系列】常用函数—聚合函数

    聚合函数平均值AVG.标准偏差STDEV.方差VAR.最大值MAX.最小值MIN.合计SUM.次数COUNT.极差值MAX-MIN.变异系数STDEV/AVG*100 什么是统计统计 就是通过样本特性 ...

  2. [转载] 一篇文章带你了解Paxos算法

    原文: http://dockone.io/article/640 [编者的话]本文是Quora上关于Paxos算法的回答,两位答者分别从不同的角度描述Paxos算法.Vineet Gupta的回答细 ...

  3. NTFS reparse point

    https://en.wikipedia.org/wiki/NTFS_reparse_point NTFS HARD link: since Windows NT4: files on the sam ...

  4. JAVASCRIPT事件详解-------原生事件基础....

    javaScirpt事件详解-原生事件基础(一)   事件 JavaScript与HTML之间的交互是通过事件实现的.事件,就是文档或浏览器窗口中发生的一些特定的交互瞬间,通过监听特定事件的发生,你能 ...

  5. android实现系统电话通话过程中自动感应黑屏

    package com.developmenttools.customui.activity; import java.util.HashSet;import java.util.Set; impor ...

  6. MyBatis——调用存储过程

    原文:http://www.cnblogs.com/xdp-gacl/p/4270352.html 一.提出需求 查询得到男性或女性的数量, 如果传入的是0就女性否则是男性 二.准备数据库表和存储过程 ...

  7. about shell

    摘抄 cat 等 cat主要有三大功能:1.一次显示整个文件.$ cat   filename2.从键盘创建一个文件.$ cat  >  filename只能创建新文件,不能编辑已有文件.3.将 ...

  8. Animation用法

    测试代码及说明: <!DOCTYPE html> <html lang="en-US"> <head> <meta charset=&qu ...

  9. mysql通过binlog日志来恢复数据

    简介 在生产的过程中有这么一个业务场景:比如我在2016-11-19 09:30:00 通过mysqldump的方式备份了数据库,但是在2016-11-19 10:30:00的时候数据库崩溃了,如果通 ...

  10. js一些题目

    假期在家,看到的,昨天看了下: 原文链接:http://wwwcqamin.duapp.com/?p=102#comment-7 请说出下面程序的输出结果 第一题: 1 2 3 4 5 6 7 8 9 ...