• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    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类型。

    image

    看一下改了之后的查询

    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不要输入过长的内容,否则会出错了。

    上一篇:一条语句简单解决“每个Y的最新X”的经典sql语句
    下一篇:SQL2000中改名和删除默认sa帐号的最安全方法
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

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