最近主导了旗下某核心项目升级到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里也有人做了测试,结果下图

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

横坐标是表里有多少数据

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

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

好消息是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了

EfCore3的OwnedType会导致Sql效率问题的更多相关文章

  1. 【转】导致SQL执行慢的原因

    索引对大数据的查询速度的提升是非常大的,Explain可以帮你分析SQL语句是否用到相关索引. 索引类似大学图书馆建书目索引,可以提高数据检索的效率,降低数据库的IO成本.MySQL在300万条记录左 ...

  2. 导致SQL执行慢的原因

    索引对大数据的查询速度的提升是非常大的,Explain可以帮你分析SQL语句是否用到相关索引. 索引类似大学图书馆建书目索引,可以提高数据检索的效率,降低数据库的IO成本.MySQL在300万条记录左 ...

  3. [MySQL优化] -- 如何查找SQL效率地下的原因

    [MySQL优化] -- 如何查找SQL效率地下的原因   来源: ChinaUnix博客 日期: 2009.07.20 16:12 (共有条评论) 我要评论       查询到效率低的 SQL 语句 ...

  4. 存储过程为什么比sql效率高

    对于存储过程为什么比sql效率高的原因有4点 第一就是使用存储过程允许组建式编成, 二是可以对程序进行编译,

  5. 最新版SEMCMS_PHP_3.5 过滤不严导致sql注入

    一.漏洞分析 在分析过程中看到网上已经有人发现semcms V2.4存在过滤不严导致sql注入的漏洞,不知道咋还没改,而且最新版过滤的关键字更少了. 首先查看首页文件index.php的代码 < ...

  6. 服务器重启可能会导致SQL Server中部分数据库变为single user mode

    今天检查公司生产服务器的SQL Server数据库,惊讶的发现有三个生产数据库变为了single user mode.奇怪的是没有任何人和程序执行过SQL语句将这三个数据库设置为single user ...

  7. Drupal V7.3.1 框架处理不当导致SQL注入

    这个漏洞本是2014年时候被人发现的,本着学习的目的,我来做个详细的分析.漏洞虽然很早了,新版的Drupal甚至已经改变了框架的组织方式.但是丝毫不影响对于漏洞的分析.这是一个经典的使用PDO,但是处 ...

  8. 修改Windows帐户密码,导致Sql Server 2000无法启动

    修改Windows帐户密码,导致Sql Server 2000无法启动. --现象以管理员或同等权限用户登录 Windows XP,建立 Sql Server 2000 数据库.之后,在修改此 Win ...

  9. 12.1.0.2自适应特性导致SQL性能下降

    背景介绍 在升级到12.1.0.2.0数据库版本后,在使用12c中引入的自适应特性默认配置的情况下,可能引起SQL性能的下降. 问题现象升级到12.1.0.2.0后,SQL语句性能可能出现下降. 影响 ...

随机推荐

  1. MySQL 8 安装教程(个人版)+创建用户

    Mysql 8的安装教程 解压到指定目录如:D:\WinInstall\mysql-8.0.19-winx64这时候你需要在根目录下创建两个文件,分别是data文件夹和my.ini文件,然后使用编辑器 ...

  2. js垃圾回收和内存泄漏

    js垃圾回收和内存泄漏 js垃圾回收 Js具有自动垃圾回收机制.垃圾收集器会按照固定的时间间隔周期性的执行. 1.标记清除(常用) 工作原理:是当变量进入环境时,将这个变量标记为"进入环境& ...

  3. Swift入门

    Swift 入门 简介 Swift 语言由苹果公司在 2014 年推出,用来撰写 OS X 和 iOS 应用程序 2014 年,在 Apple WWDC 发布 历史 2010 年 7 月,苹果开发者工 ...

  4. vue项目Windows Server服务器部署IIS设置Url重写

    1.将vue项目使用npm run build命令打包后将dist文件夹内的文件全部拷贝到服务器. 2.IIS添加应用程序池,.NET CLR版本选择无托管代码 3.添加网站,应用程序池选择刚刚添加的 ...

  5. JVM运行时数据区--本地方法栈

    本地方法栈 1.Java虚拟机栈用于管理Java方法的调用,而本地方法栈用于管理本地方法(一般非Java实现的方法)的调用 2.本地方法栈,也是线程私有的. 3.允许被实现成固定或者是可动态拓展的内存 ...

  6. Spock测试套件入门

    目录 Spock测试套件 核心概念 整体认识 前置.后置 同junit的类比 Feature 方法 blocks 典型的用法 异常condition then和expect的区别 cleanup bl ...

  7. python中圆周率的计算

    蒙特卡罗方法计算圆周率 蒙特卡罗方法是一个撒点方法,取一个正圆的四分之一,和一个正方形的四分之一 形成一个单位方形,单位四分之一圆和四分之一正方形之比,就构成了圆周率 向这个区域撒点,如果点落在圆内部 ...

  8. RXJAVA之Subject

    RxJava中常见的Subject有4种,分别是 AsyncSubject. BehaviorSubject.PublishSubject. ReplaySubject. AsyncSubject 使 ...

  9. Java文件操作API功能与Windows DOS命令和Linux Shell 命令类比

    Java文件操作API功能与Windows DOS命令和Linux Shell 命令类比: Unix/Linux (Bash) Windows(MS-DOS) Java 进入目录 cd cd - 创建 ...

  10. 浅谈Java多线程

    线程与进程 什么是进程? 当一个程序进入内存中运行起来它就变为一个进程.因此,进程就是一个处于运行状态的程序.同时进程具有独立功能,进程是操作系统进行资源分配和调度的独立单位. 什么是线程? 线程是进 ...