• EfCore3的OwnedType会导致Sql效率问题


    最近主导了旗下某核心项目升级到EfCore3

    由于之前Core2升级时候也踩过不少的坑很多东西都有规划和准备,整体上还是没出太大问题

    但是最近突然发现efcore对于使用了ownedType的生成语句有问题

    查找了一下资料发现已经有人在efcore的github上开了issus了,并且还讨论的蛮多的了

    https://github.com/dotnet/efcore/issues/18299 

    鉴于很多人看到一堆E文后会直接放弃,下面我简单阐述下这个问题

    EfCore自2.0的时候引入了一个叫OwnedType的特性,是用于完善之前EfCore1.x相比于Ef6使其少了的ComplexType特性

    正常来说我们用Ef的时候是一个类映射到一个表,但是有时候某些表字段过多的情况下,我们可能会想整理下把一个表里某些信息放到一个子类里,但是其他信息还是在主类

    形如

    class Order
    {
        public int Id { get; set; }
        public string Title { get; set; }
        public Address Address { get; set; }
    }
    
    class Address
    {
        public string Street { get; set; }
        public string City { get; set; }
    }
    
    
    然后DbContext里配置下  
    modelBuilder.Entity<Order>().OwnsOne(x => x.Address);  
    
    
    这种情况下最理想生成的语句应该是类似  
    select Id,Title,Street,City from Orders
     这个样子的形式才对,然后EfCore内部再通过自己映射的形式把后面4个字段映射到Author类里的Address这个类里
    
    
    但是在EfCore3里他生成的语句是形如  
    SELECT o."Id", o."Title", t."Id", t."Address_City", t."Address_Street"
          FROM "Orders" AS o
          LEFT JOIN (
              SELECT o0."Id", o0."Address_City", o0."Address_Street", o1."Id" AS "Id0"
              FROM "Orders" AS o0
              INNER JOIN "Orders" AS o1 ON o0."Id" = o1."Id"
              WHERE (o0."Address_Street" IS NOT NULL) OR (o0."Address_City" IS NOT NULL)
          ) AS t ON o."Id" = t."Id"
          WHERE (t."Id" IS NULL)

    尽管严格来说这个并不影响逻辑,但是这样子join的话对Sql的性能和效率有挺不好的负面影响

    就那个issus里也有人做了测试,结果下图

    image

    纵坐标是每秒执行的查询数(简单理解为并发数吧)

    横坐标是表里有多少数据

    可以看到表的数据量上升之后使用了OwnedType的EfCore3会出现显著下滑(自己join自己多了)

    另外该问题在EfCore2的时候是没有的,就Core3才有(直觉是Core3的OwnedType被魔改了可以支持OwnsMany等的支持的时候引入的)

    接下来就是一个好消息和一个坏消息了

    好消息是EfCore那边认可了这个问题然后当前EfCore 5 preview-3修复了这个问题

    坏消息是至少目前确认这个修复不会合并到EfCore3.1.x(后期会不会有变数不清楚)

    感觉这个蛮坑的,一般公司用的话都会是优先选用LTS,而当前的LTS就是3.1

    而接下来的NetCore5(含EfCore5)并不是LTS所以对于公司组织的线上采用率应该会相对较低

    那难道修复这个问题还要等一个目前还没规划的NetCore5.1?那是不是要等的有点儿太久了

    最后,如果有升级EfCore3的且用了OwnedType(相当于Ef6时期的ComplexType)请谨慎评估下这个问题对你可能造成的影响

    毕竟目前看起来,降级回去不大可能,烧香保佑下fix path能到3.1.x要么就只能指望Core5.1了

  • 相关阅读:
    常见的行元素与块元素
    [转]SVN服务器部署并实现双机同步及禁止普通用户删除文件
    [转]Axure共享工程Shared Project(二):编辑修改和提交
    如何添加网络打印机
    [转]JSON 转换异常 死循环 There is a cycle in the hierarchy
    比较常用的Properties配置文件的使用方法示例
    解决Tomcat项目重复加载导致pemgen space内存溢出
    怎样批量删除.svn文件
    [转]前端工程师必须掌握的知识点
    Freemarker 使用
  • 原文地址:https://www.cnblogs.com/leolaw/p/13832937.html
Copyright © 2020-2023  润新知