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

孙晗语1314

孙晗语1314

2016-02-19 10:54

每个人都希望每天都是开心的,不要因为一些琐事扰乱了心情还,闲暇的时间怎么打发,关注图老师可以让你学习更多的好东西,下面为大家推荐LINQ to SQL:处理char(1)字段的方式会引起全表扫描问题,赶紧看过来吧!

image 

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

image image 表定义生成的实体

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',则可以使用索引。我们看下这二种情况时的查询执行计划对比。

image

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

3.

对策

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

(本文来源于图老师网站,更多请访问https://m.tulaoshi.com/bianchengyuyan/)

image

(本文来源于图老师网站,更多请访问https://m.tulaoshi.com/bianchengyuyan/)

看一下改了之后的查询

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.8Linqsql

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

展开更多 50%)
分享

猜你喜欢

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

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

SQL Server 2005中处理表分区问题

编程语言 网络编程
SQL Server 2005中处理表分区问题

s8lol主宰符文怎么配

英雄联盟 网络游戏
s8lol主宰符文怎么配

怎么导出SQL所有用户表的字段信息

SQLServer
怎么导出SQL所有用户表的字段信息

Mysql如何避免全表扫描的方法

编程语言 网络编程
Mysql如何避免全表扫描的方法

lol偷钱流符文搭配推荐

英雄联盟 网络游戏
lol偷钱流符文搭配推荐

如何用sql语句修改数据表中字段 实现identity(100,1)

SQLServer
如何用sql语句修改数据表中字段 实现identity(100,1)

SQL中char和varchar的效率分析

SQLServer
SQL中char和varchar的效率分析

lolAD刺客新符文搭配推荐

英雄联盟
lolAD刺客新符文搭配推荐

U盘读不出来的解决步骤

U盘读不出来的解决步骤

数据排序谁最快(javascript中的Array.prototype.sort PK 快速排序)

数据排序谁最快(javascript中的Array.prototype.sort PK 快速排序)
下拉加载更多内容 ↓