.Where(o => SqlMethods.Like(o.Count.ToString(), "abc")) 如何用表达式树构造出来?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了.Where(o => SqlMethods.Like(o.Count.ToString(), "abc")) 如何用表达式树构造出来?相关的知识,希望对你有一定的参考价值。

参考技术A 为什么要主动构件表达式树?你可以直接写一个方法接收IQueryable的参数和like的字符串,返回Expression,方法体内写return queryable.Where(o => SqlMethods.Like(o.Count.ToString(), likeText));

为啥当我的查询有 Where 时 SQL Server 有更多的 I/O?

【中文标题】为啥当我的查询有 Where 时 SQL Server 有更多的 I/O?【英文标题】:Why SQL Server has more I/O when my query has Where?为什么当我的查询有 Where 时 SQL Server 有更多的 I/O? 【发布时间】:2014-12-03 00:53:29 【问题描述】:

我使用SQL Server 2012 并编写此查询:

DBCC DROPCLEANBUFFERS;
SET STATISTICS IO ON; 

我在上面写了两行用于清洁现金并设置统计信息。

这些是我的查询:

SELECT C.custid, C.companyname, O.orderid, O.orderdate 
FROM Sales.Customers AS C 
     INNER JOIN Sales.Orders AS O 
        ON C.custid = O.custid 

SELECT C.custid, C.companyname, O.orderid, O.orderdate 
FROM Sales.Customers AS C 
    INNER JOIN Sales.Orders AS O 
        ON C.custid = O.custid 
WHERE O.custid < 5

但我得到了这个统计数据:

对于第一个查询: (受影响的 830 行) 表“工作台”。扫描计数 0,逻辑读取 0,物理读取 0, 预读读取 0,lob 逻辑读取 0,lob 物理读取 0,lob 预读读取 0。 表“订单”。扫描计数 1,逻辑读取 21,物理读取 1, 预读读取 25,lob 逻辑读取 0,lob 物理读取 0,lob 预读读取 0。 表“客户”。扫描计数 1,逻辑读取 2,物理读取 1, 预读读取 0,lob 逻辑读取 0,lob 物理读取 0,lob 预读读取 0。

对于第二个查询: (30 行受影响) 表“客户”。扫描计数 0,逻辑读取 60,物理读取 1, 预读读取 0,lob 逻辑读取 0,lob 物理读取 0,lob 预读读取 0。 表“订单”。扫描计数 1,逻辑读取 21,物理读取 0,预读读取 0, lob 逻辑读取 0,lob 物理读取 0,lob 预读读取 0。

考虑到行数,为什么第二个查询中的logical reads 比第一个要多?

【问题讨论】:

【参考方案1】:

无条件:

Table 'Customers'. Scan count 1, logical reads 2

有条件:

Table 'Customers'. Scan count 0, logical reads 60,

区别在于第一种情况下的扫描(速度很快,因为表很小)与通过索引的重复随机访问(不是那么快,因为表太小而无法理解) )。

但是请注意,由嵌套循环连接引起的所有这些重复的逻辑读取不会导致实际的 I/O(物理读取),因为它们会一遍又一遍地访问相同的几个块(这些块在您的缓冲区缓存工作集)。

这会给您带来性能问题吗?看起来查询已经足够快了。希望优化器能正确处理真正重要的情况(即涉及大表的情况)。

【讨论】:

谢谢,什么是 Worktable? 这是用于收集 JOIN 数据的临时结构。第二个查询显然不需要它,因为这是通过索引访问直接选择行。您可以为这两个查询附加执行计划。这应该会显示更多细节。 你有它:哈希联接(需要工作表)与嵌套循环【参考方案2】:

也许第一个查询可以使用索引,而第二个查询不能。 custid 可能只是一个包含列,而不是索引中的键列。 您可以在执行计划中看到这一点。

【讨论】:

这很有趣。我将在我的 Owen SQL 安装中对此进行测试。但是现在,我会检查 Sales.Orders 上是否有索引,其中 custid 作为键,orderid 和 orderdate 作为 INCLUDED 列

以上是关于.Where(o => SqlMethods.Like(o.Count.ToString(), "abc")) 如何用表达式树构造出来?的主要内容,如果未能解决你的问题,请参考以下文章

LINQ to SQL语句之Top/Bottom和Paging和SqlMethods

LINQ体验——LINQ to SQL语句之Union All/Union/Intersect和Top/Bottom和Paging和SqlMethods

LINQ OrderBy 和 Where 结合

var query = dt.AsEnumerable().ToList().Where(o => o.Field<string>("CampaignName")

在 LINQ to Entities 查询中无法构造实体或复杂类型“Cits.Data.LineImg”。

lambda 查询的优化