LINQ to SQL:处理char(1)字段的方式会引起全表扫描问题

如果表中的字段类型为 char(1) 时,Linq to SQL生成char (System.Char)的属性,如下图








表定义 生成的实体

2.

如果要查询LineCode=='A'的记录,可以这样定义Linq查询语句










var test1 = from p in db.ProductLines
            where p.LineCode =='A'
            select p;

生成的SQL语句是这样的












SELECT [t0].[LineCode], [t0].[LineName], [t0].[JPH], [t0].[QueueCount]
FROM [dbo].[ProductLine] AS [t0]
WHERE UNICODE([t0].[LineCode]) = @p0
-- @p0: Input Int (Size = 0; Prec = 0; Scale = 0) [65]
-- Context: SqlProvider(Sql2000) Model: AttributedMetaModel Build: 3.5.21022.8

注意到Where语句了吗?是WHERE UNICODE([t0].[LineCode]) = 65,这里先取LineCode列内容的UNICODE再和'A'的UNICODE比较。我们知道'A'和'a'的UNICODE是不同的。UNICODE('A') =65,UNICODE('a')=97,也就是说,我们在Linq to SQL中这二个查询的结果是不一样的。










Linq 语句










var test1 = from p in db.ProductLines
            where p.LineCode =='a'
            select p;










var test1 = from p in db.ProductLines
            where p.LineCode =='A'
            select p;

生成SQL语句










SELECT [t0].[LineCode], [t0].[LineName], [t0].[JPH], [t0].[QueueCount]
FROM [dbo].[ProductLine] AS [t0]
WHERE UNICODE([t0].[LineCode]) = @p0
-- @p0: Input Int (Size = 0; Prec = 0; Scale = 0) [97]










SELECT [t0].[LineCode], [t0].[LineName], [t0].[JPH], [t0].[QueueCount]
FROM [dbo].[ProductLine] AS [t0]
WHERE UNICODE([t0].[LineCode]) = @p0
-- @p0: Input Int (Size = 0; Prec = 0; Scale = 0) [65]

明显,在Linq to sql是查询char(1)类型字段是区分大小写的

这还会导致一个比较严重的问题,我们知道在SQL Server中,任何在运算符左边的操作都会使SQL采用全表扫描。也就是说,Linq的这个查询,会引起全表扫描,即使[LineCode]列上定义了聚合索引。而如果是where [linecode]='A',则可以使用索引。我们看下这二种情况时的查询执行计划对比。

图中可以看出,Linq to SQL 生成的SQL语句是表扫描,而后者则是索引查找。

3.

对策

在DBML设计器中将LineCode改成string类型。

看一下改了之后的查询

















var test1 = from p in db.ProductLines
            where p.LineCode == "a"
            select p;












SELECT [t0].[LineCode], [t0].[LineName], [t0].[JPH], [t0].[QueueCount]
FROM [dbo].[ProductLine] AS [t0]
WHERE [t0].[LineCode] = @p0
-- @p0: Input VarChar (Size = 1; Prec = 0; Scale = 0) [a]
-- Context: SqlProvider(Sql2000) Model: AttributedMetaModel Build: 3.5.21022.8

Linq sql

改为string后,生成的SQL不再用UNICODE函数了,就解决了区分大小写和引起全表扫描的问题。但又引起一个新的问题,因为数据库中存储的数据长度是1,在Insert和Update时就要注意,LineCode不要输入过长的内容,否则会出错了。

(0)

相关推荐

  • LINQ to SQL:处理char(1)字段的方式会引起全表扫描问题

    如果表中的字段类型为 char(1) 时,Linq to SQL生成char (System.Char)的属性,如下图 表定义 生成的实体 2. 如果要查询LineCode=='A'的记录,可以这样定义Linq查询语句 var test1 = from p in db.ProductLines             where p.LineCode =='A'             select p; 生成的SQL语句是这样的 SELECT [t0].[LineCode], [t0].[Li

  • SQL中WHERE变量IS NULL条件导致全表扫描问题的解决方法

    复制代码 代码如下: SET @SQL = 'SELECT * FROM Comment with(nolock) WHERE 1=1    And (@ProjectIds Is Null or ProjectId = @ProjectIds)    And (@Scores is null or Score =@Scores)' 印象中记得,以前在做Oracle开发时,这种写法是会导致全表扫描的,用不上索引,不知道Sql Server里是否也是一样呢,于是做一个简单的测试1.建立测试用的表结

  • 数据库SQL调优的几种方式汇总

    目录 char  vs varchar 开启慢查询日志来定位查询慢的语句 合理使用关键字 优化查询缓存 适当使用索引 分割数据表 非规范化的方式 总结 最近在复习SQL调优,总结了下主要有以下几种方式: char  vs varchar 1.如果文本字段始终是固定长度的(例如,US 邮编,其始终具有“XXXXX-XXXX”形式的规范表示),那么推荐使用char.varchar 类型的长度是可变的,而 char 类型是一个定长的字段,以 char(10) 为例,不管真实的存储内容多大或者是占了多少

  • Linq to SQL Delete时遇到问题的解决方法

    1.1. Code1: using (PubsDataContext pubsContent = new PubsDataContext()) {     pubsContent.Log = Console.Out;     Author author = pubsContent.Authors.Single(a => a.au_id == "111-11-1111");     pubsContent.Authors.DeleteOnSubmit(author);     pu

  • asp.net使用LINQ to SQL连接数据库及SQL操作语句用法分析

    本文实例讲述了asp.net使用LINQ to SQL连接数据库及SQL操作语句用法.分享给大家供大家参考,具体如下: LINQ简介 LINQ:语言集成查询(Language INtegrated Query)是一组用于c#和Visual Basic语言的扩展.它允许编写C#或者Visual Basic代码以查询数据库相同的方式操作内存数据. LINQ是一门查询语言,和SQL一样,通过一些关键字的组合,实现最终的查询. LINQ的分类 LINQ to Object LINQ to XML LIN

  • 解决mybatis使用char类型字段查询oracle数据库时结果返回null问题

    同事在学mybatis时,遇到了一个问题就是,使用char类型字段作为查询条件时一直都查不出数据,其他类型的则可以. 使用的数据库是oracle,查询条件字段类型是char(50),java代码对应的是String类型. 后来经过排查,是由于在oracle中,char类型字段,如果内容长度不够,会自动以空格方式补足长度.如字段 name char(5),若值为sgl,那么oracle会自动用空格补足长度,最终值为sgl. 一.解决方法: 方法1:先用trim()函数把值去掉两边空格再作为条件查询

  • linq to sql 中,如何解决多条件查询问题,答案,用表达式树! (下)

    如何从真正意义上做到延迟加载,即一次只从数据库中取我们需要的用到的那部分数据呢.通过研究,有了下面的方法: 首先,我们要新建一个静态类,用于存放多条件组合查询的各种组合,比如or,And这些等等.代码如下: 复制代码 代码如下: using System.Linq.Expressions; public static class PredicateExtensionses { public static Expression<Func<T, bool>> True<T>

  • linq to sql中,如何解决多条件查询问题,答案,用表达式树!

    本篇适合于规模较小的数据量,对于大数据量,需要用另外的方式,见下一篇 首先,从网上搜,是必不可少的,大概了解了一下linq 多条件组合查询的方向,就开始动手了,首先,写一个委托的方法: 复制代码 代码如下: private bool GetCondition(FeedBack fb) { bool boolResult = true; int f_type = Int32.Parse(ddlFType.SelectedValue); int isClose = Int32.Parse(ddlIs

  • C#操作LINQ to SQL组件进行数据库建模的基本教程

    建立实体类 使用LINQ to SQL时,需要首先建立用于映射数据库对象的模型,也就是实体类.在运行时,LINQ to SQL 根据LINQ表达式或查询运算符生成SQL语句,发送到数据库进行操作.数据库返回后,LINQ to SQL负责将结果转换成实体类对象. 建立实体类的方法有很多,例如LINQ to SQL设计器,手动编码建立,使用XML文件映射,使用命令行工具SqlMetal生成等.其中最方便的就是LINQ to SQL设计器. 1.使用LINQ to SQL设计器建立实体类       

  • Django ORM 自定义 char 类型字段解析

    用 CharField 定义的字段在数据库中存放为 verchar 类型 自定义 char 类型字段需要下面的代码: class FixedCharField(models.Field): """ 自定义的 char 类型的字段类 """ def __init__(self, max_length, *args, **kwargs): self.max_length = max_length super(FixedCharField, self)

随机推荐