我们知道,在sql中使用IN让我们的where子句可以规定多个值。当需要从一个集合中查询包含某几个值的记录的时候,通常我们会选择使用IN来实现,其实,使用JOIN也可以实现这样的功能,而且性能要比IN好。我会从以下几个方面来进行总结。
- 使用IN和JOIN的性能对比
- EF中如何使用JOIN来代替IN
使用IN和JOIN的性能对比
首先来看一段sql语句,然后通过执行计划来比较它们之间的性能。
使用IN和JOIN查询的代码:
下面是它们的执行计划:
通过执行计划,可以看到使用JOIN的性能要比IN好。
EF中如何使用JOIN来代替IN
我们在使用EF的时候, 会有很多像下面这样的查询。
1 List<int> productIds = new List<int> 2 { 3 15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30 4 }; 5 using (var db = new PackageFHContext()) 6 { 7 var containerResult = db.ProductMasterSet.Where(p => productIds.Contains(p.ProductID)); 8 }
实际上,这种写法生成的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函数来实现,代码如下。
1 List<int> productIds = new List<int> 2 { 3 15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30 4 }; 5 using (var db = new PackageFHContext()) 6 { 7 var joinResult = from p in db.ProductMasterSet 8 join c in db.CLR_Split(string.Join(",", productIds), ",", true) on p.ProductID.ToString() equals c.id 9 select p; 10 }
这里使用了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];
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架