当前位置: 首页 > 面试题库 >

doctrine2-如何提高冲洗效率?

易奇希
2023-03-14
问题内容

我必须更新我的Doctrine实体以匹配(可能很大)XML文件中的记录。我还必须根据XML中的数据更新ManyToMany关联。这是我在循环内执行的操作:

  1. 从XML获取数据
  2. 从数据库获取实体(如果不存在,则创建新实体)
  3. 设置新实体属性
  4. 获取当前的实体关联(getter返回ArrayCollection对象)
  5. 清除所有关联(通过调用ArrayCollection::clear()
  6. 设置新的关联(通过ArrayCollection::add()在子循环中调用)
  7. 由EntityManager保留实体

*循环 *后 ,我打电话EntityManager::flush()

问题在于,刷新会产生大量查询,而不是立即更新/插入/删除多行。对于每个实体,执行以下查询:

  • 选择从数据库获取实体
  • UPDATE以更新实体属性(由于没有更改属性,因此现在实际上已跳过……)
  • 删除以清除以前的关联
  • 插入以插入新的关联

所以总共以XML记录了305条记录,我得到915个查询(如果所有实体都会更改,我想最多可以查询1220个查询),这使导入非常缓慢。

我可以在循环之前利用IdentityMap和预取实体,但是仍然有UPDATE / DELETE / INSERT查询。

  • 有没有一种方法可以使flush方法更好地优化查询(使用多插入,WHERE IN而不是多个DELETE查询等)?
  • 这是刷新方法的正常行为,还是我做错了什么?
  • 也许我更新实体关联的方式存在问题。有更好的方法做到这一点吗?(而不是“获取/清除/添加”方法)
  • 我知道Doctrine并非用于批量提取处理,但我认为将其用于XML导入是避免非ORM方法可能出现的数据库不一致的最佳方法。那正确吗?
  • 如果以上方法有误,应如何解决?

问题答案:

您做对了-这只是很慢,因为添加的ORM抽象意味着您无法进行所需的优化。

就是说,EntityManager在这么大的事务上确实变慢。如果您绝对不需要在一个大事务中全部使用它们,则可以通过flush()ing然后每20-200次循环clear()清除EM来获得性能更高的代码。

如果那不能给您足够的性能,我能想到的唯一替代方法是还原为直接对DBMS运行自定义SQL的自定义代码。

我知道这不是一个很好的答案,但是至少我可以告诉你,你并不疯狂。

------编辑------

摘自Doctrine2有关批处理的官方文章:

某些人似乎想知道为什么Doctrine不使用多重插入(将插入到(…)值(…),(…),(…),…

首先,此语法仅在mysql和较新的postgresql版本上受支持。其次,当使用AUTO_INCREMENT或SERIAL且ORM需要使用这些标识符进行对象的身份管理时,没有一种简单的方法可以在这种多插入中获取所有生成的标识符。最后,插入性能很少是ORM的瓶颈。普通插入在大多数情况下已经足够快,如果您真的想进行快速批量插入,那么无论如何多插入都不是最好的方法,即Postgres
COPY或Mysql LOAD DATA INFILE快几个数量级。

这就是为什么不值得在ORM中实现在mysql和postgresql上执行多插入的抽象的原因。

当使用 远程 数据库 与本地
数据库时,由于将每个查询发送到远程服务器的开销也很大,因此性能上也存在显着差异。借助事务和数据库优化,使用本地数据库时的开销要低得多。(例如,在问题示例中,70秒降低到300ms)



 类似资料:
  • 我想在使用OpenCV和Tesseract时检测图像中的文本。我的步骤是: 为了检测文本,我使用了CV::text的场景文本检测算法。这实际上在困难的情况下也很有效 分别标识文本从主图像中提取包含文本的图像区域 我将每个子图像传递给Tesseract 然而,tesseract几乎找不到文本,如果它找到了文本,它就错了。示例:(图片取自https://github.com/opencv/opencv

  • 本文向大家介绍如何利用FutureBuilder提高开发效率,包括了如何利用FutureBuilder提高开发效率的使用技巧和注意事项,需要的朋友参考一下 常见场景 展示请求按钮 用户点击按钮,显示loading 展示数据或者错误 抽象模式 展示请求按钮(初始状态) 用户点击按钮,显示loading(请求中状态) 展示数据或者错误 (结束状态(成功或失败)) 转换成程序语言 以上三种现实情况对应

  • 本文向大家介绍如何提高组件的渲染效率呢?相关面试题,主要包含被问及如何提高组件的渲染效率呢?时的应答技巧和注意事项,需要的朋友参考一下 function Child({seconds}){ console.log('I am rendering'); return ( I am update every {seconds} seconds ) }; export default React.mem

  • 问题内容: 我在php页面中使用了无限循环功能,它每秒都会回显一个文本。当我在浏览器中打开页面时,它起作用了!但是当我通过jquery ajax加载它时没有响应! php页面 jQuery代码 问题答案: 不能仅使用$ .get来完成HTTP流传输 插入如下:http : //ajaxpatterns.org/archive/HTTP_Streaming.php。 HTTP流是一个非常复杂的技巧。

  • 问题内容: '; ob_flush(); flush(); 我有专用的服务器,因此可以进行更改。我正在运行apache和nginx作为代理服务器。 问题答案: 您正在使用,而没有,因此没有需要冲洗的东西。 它还取决于Web服务器和代理及其设置。 您应该禁用Nginx的缓冲(添加到配置文件并重新启动Nginx) 另外,检查您的 php.ini是否 包含和。

  • 本文向大家介绍C++ 冲洗刷新流,包括了C++ 冲洗刷新流的使用技巧和注意事项,需要的朋友参考一下 示例 默认情况下,文件流以及许多其他类型的流都被缓冲。这意味着写入流可能不会导致基础文件立即更改。为了迫使所有缓冲的写操作立即进行,可以刷新流。您可以直接通过调用flush()方法或通过std::flush流操纵器来执行此操作: 有一个流操纵器std::endl,结合了编写换行符和刷新流: 缓冲可以