【问题标题】:unknow query after flushing with doctrine and fosrestbundle in symfony在 symfony 中使用学说和 fosrestbundle 刷新后的未知查询
【发布时间】:2016-02-09 21:38:31
【问题描述】:

在此感谢您对我的帮助,我被 symfony 中的教义和 fosrestbundle 的未知行为困扰了一周。

我有 2 个具有多对多关系的实体:产品和类别

自从上周我在 productRESTcontroller 上发送补丁请求以更新实体之间的关系以来,一切正常,在刷新后,通常它会返回更新后的实体。 但是现在,它更新了实体,但它也进行了很多“SELECT”查询,这是我从未做过的。

  • 请求是用 guzzle 创建和执行的,它是一个承诺(异步请求)
  • productRESTcontroller 是使用 voryxRestGeneratorBundle 与 fosrestbundle 和 jmsserializerbundle 一起创建的

我删除了学说缓存、symfony 缓存等,尝试了许多其他方法来更新实体,但没有解决这个问题。

我可以在日志中看到:

[2015-11-09 09:26:58] doctrine.DEBUG: "START TRANSACTION" [] []
[2015-11-09 09:26:58] doctrine.DEBUG: UPDATE Category SET name = ? WHERE id = ? ["EXPRESS",10152] []
[2015-11-09 09:26:58] doctrine.DEBUG: "COMMIT" [] []
[2015-11-09 09:26:58] doctrine.DEBUG: SELECT t0.id AS id1, t0.id_prod_dist AS id_prod_dist2, t0.ref_prod AS ref_prod3, t0.on_sale AS on_sale4, t0.price AS price5, t0.ecotax AS ecotax6, t0.ean13 AS ean137, t0.active AS active8, t0.id_default_image AS id_default_image9, t0.name AS name10, t0.id_cats AS id_cats11, t0.id_combis AS id_combis12, t0.link_rewrite AS link_rewrite13, t0.weight_product AS weight_product14, t0.maj_auto AS maj_auto15 FROM Product t0 INNER JOIN product_category ON t0.id = product_category.product_id WHERE product_category.category_id = ? [10152] []
[2015-11-09 09:26:58] doctrine.DEBUG: SELECT t0.id AS id1, t0.id_cat_dist AS id_cat_dist2, t0.name AS name3, t0.active AS active4, t0.maj_auto AS maj_auto5, t0.erasable AS erasable6, t0.ids_products AS ids_products7, t0.url_cat AS url_cat8 FROM Category t0 INNER JOIN product_category ON t0.id = product_category.category_id WHERE product_category.product_id = ? [14] []
[2015-11-09 09:26:58] doctrine.DEBUG: SELECT t0.id AS id1, t0.id_prod_dist AS id_prod_dist2, t0.ref_prod AS ref_prod3, t0.on_sale AS on_sale4, t0.price AS price5, t0.ecotax AS ecotax6, t0.ean13 AS ean137, t0.active AS active8, t0.id_default_image AS id_default_image9, t0.name AS name10, t0.id_cats AS id_cats11, t0.id_combis AS id_combis12, t0.link_rewrite AS link_rewrite13, t0.weight_product AS weight_product14, t0.maj_auto AS maj_auto15 FROM Product t0 INNER JOIN product_category ON t0.id = product_category.product_id WHERE product_category.category_id = ? [10180] []
[2015-11-09 09:26:58] doctrine.DEBUG: SELECT t0.id AS id1, t0.id_cat_dist AS id_cat_dist2, t0.name AS name3, t0.active AS active4, t0.maj_auto AS maj_auto5, t0.erasable AS erasable6, t0.ids_products AS ids_products7, t0.url_cat AS url_cat8 FROM Category t0 INNER JOIN product_category ON t0.id = product_category.category_id WHERE product_category.product_id = ? [12] []
[2015-11-09 09:26:58] doctrine.DEBUG: SELECT t0.id AS id1, t0.id_prod_dist AS id_prod_dist2, t0.ref_prod AS ref_prod3, t0.on_sale AS on_sale4, t0.price AS price5, t0.ecotax AS ecotax6, t0.ean13 AS ean137, t0.active AS active8, t0.id_default_image AS id_default_image9, t0.name AS name10, t0.id_cats AS id_cats11, t0.id_combis AS id_combis12, t0.link_rewrite AS link_rewrite13, t0.weight_product AS weight_product14, t0.maj_auto AS maj_auto15 FROM Product t0 INNER JOIN product_category ON t0.id = product_category.product_id WHERE product_category.category_id = ? [10186] []
[2015-11-09 09:26:58] doctrine.DEBUG: SELECT t0.id AS id1, t0.id_cat_dist AS id_cat_dist2, t0.name AS name3, t0.active AS active4, t0.maj_auto AS maj_auto5, t0.erasable AS erasable6, t0.ids_products AS ids_products7, t0.url_cat AS url_cat8 FROM Category t0 INNER JOIN product_category ON t0.id = product_category.category_id WHERE product_category.product_id = ? [13] []
[2015-11-09 09:26:58] doctrine.DEBUG: SELECT t0.id AS id1, t0.id_prod_dist AS id_prod_dist2, t0.ref_prod AS ref_prod3, t0.on_sale AS on_sale4, t0.price AS price5, t0.ecotax AS ecotax6, t0.ean13 AS ean137, t0.active AS active8, t0.id_default_image AS id_default_image9, t0.name AS name10, t0.id_cats AS id_cats11, t0.id_combis AS id_combis12, t0.link_rewrite AS link_rewrite13, t0.weight_product AS weight_product14, t0.maj_auto AS maj_auto15 FROM Product t0 INNER JOIN product_category ON t0.id = product_category.product_id WHERE product_category.category_id = ? [10192] []
[2015-11-09 09:26:58] doctrine.DEBUG: SELECT t0.id AS id1, t0.id_cat_dist AS id_cat_dist2, t0.name AS name3, t0.active AS active4, t0.maj_auto AS maj_auto5, t0.erasable AS erasable6, t0.ids_products AS ids_products7, t0.url_cat AS url_cat8 FROM Category t0 INNER JOIN product_category ON t0.id = product_category.category_id WHERE product_category.product_id = ? [1] []
[2015-11-09 09:26:58] doctrine.DEBUG: SELECT t0.id AS id1, t0.id_prod_dist AS id_prod_dist2, t0.ref_prod AS ref_prod3, t0.on_sale AS on_sale4, t0.price AS price5, t0.ecotax AS ecotax6, t0.ean13 AS ean137, t0.active AS active8, t0.id_default_image AS id_default_image9, t0.name AS name10, t0.id_cats AS id_cats11, t0.id_combis AS id_combis12, t0.link_rewrite AS link_rewrite13, t0.weight_product AS weight_product14, t0.maj_auto AS maj_auto15 FROM Product t0 INNER JOIN product_category ON t0.id = product_category.product_id WHERE product_category.category_id = ? [10204] []
[2015-11-09 09:26:58] doctrine.DEBUG: SELECT t0.id AS id1, t0.id_cat_dist AS id_cat_dist2, t0.name AS name3, t0.active AS active4, t0.maj_auto AS maj_auto5, t0.erasable AS erasable6, t0.ids_products AS ids_products7, t0.url_cat AS url_cat8 FROM Category t0 INNER JOIN product_category ON t0.id = product_category.category_id WHERE product_category.product_id = ? [11] []
[2015-11-09 09:26:58] doctrine.DEBUG: SELECT t0.id AS id1, t0.supplier_reference AS supplier_reference2, t0.price AS price3, t0.weight AS weight4, t0.colisage AS colisage5, t0.in_catalog AS in_catalog6, t0.product_id AS product_id7, t0.supplier_id AS supplier_id8 FROM ProductSupplier t0 WHERE t0.product_id = ? [11] []
[2015-11-09 09:26:58] doctrine.DEBUG: SELECT t0.id AS id1, t0.refCombi AS refCombi2, t0.idProdAttrDist AS idProdAttrDist3, t0.ean13 AS ean134, t0.idProdDist AS idProdDist5, t0.weight AS weight6, t0.price AS price7, t0.ecotax AS ecotax8, t0.majAuto AS majAuto9, t0.erasable AS erasable10, t0.options_ids AS options_ids11, t0.image_ids AS image_ids12, t0.product_id AS product_id13 FROM Combination t0 WHERE t0.product_id = ? [11] []
[2015-11-09 09:26:58] doctrine.DEBUG: SELECT t0.id AS id1, t0.id_cat_dist AS id_cat_dist2, t0.name AS name3, t0.active AS active4, t0.maj_auto AS maj_auto5, t0.erasable AS erasable6, t0.ids_products AS ids_products7, t0.url_cat AS url_cat8 FROM Category t0 INNER JOIN product_category ON t0.id = product_category.category_id WHERE product_category.product_id = ? [17] []
[2015-11-09 09:26:58] doctrine.DEBUG: SELECT t0.id AS id1, t0.supplier_reference AS supplier_reference2, t0.price AS price3, t0.weight AS weight4, t0.colisage AS colisage5, t0.in_catalog AS in_catalog6, t0.product_id AS product_id7, t0.supplier_id AS supplier_id8 FROM ProductSupplier t0 WHERE t0.product_id = ? [17] []
[2015-11-09 09:26:58] doctrine.DEBUG: SELECT t0.id AS id1, t0.refCombi AS refCombi2, t0.idProdAttrDist AS idProdAttrDist3, t0.ean13 AS ean134, t0.idProdDist AS idProdDist5, t0.weight AS weight6, t0.price AS price7, t0.ecotax AS ecotax8, t0.majAuto AS majAuto9, t0.erasable AS erasable10, t0.options_ids AS options_ids11, t0.image_ids AS image_ids12, t0.product_id AS product_id13 FROM Combination t0 WHERE t0.product_id = ? [17] []
[2015-11-09 09:26:58] doctrine.DEBUG: SELECT t0.id AS id1, t0.id_cat_dist AS id_cat_dist2, t0.name AS name3, t0.active AS active4, t0.maj_auto AS maj_auto5, t0.erasable AS erasable6, t0.ids_products AS ids_products7, t0.url_cat AS url_cat8 FROM Category t0 INNER JOIN product_category ON t0.id = product_category.category_id WHERE product_category.product_id = ? [25] []
[2015-11-09 09:26:58] doctrine.DEBUG: SELECT t0.id AS id1, t0.supplier_reference AS supplier_reference2, t0.price AS price3, t0.weight AS weight4, t0.colisage AS colisage5, t0.in_catalog AS in_catalog6, t0.product_id AS product_id7, t0.supplier_id AS supplier_id8 FROM ProductSupplier t0 WHERE t0.product_id = ? [25] []
[2015-11-09 09:26:58] doctrine.DEBUG: SELECT t0.id AS id1, t0.refCombi AS refCombi2, t0.idProdAttrDist AS idProdAttrDist3, t0.ean13 AS ean134, t0.idProdDist AS idProdDist5, t0.weight AS weight6, t0.price AS price7, t0.ecotax AS ecotax8, t0.majAuto AS majAuto9, t0.erasable AS erasable10, t0.options_ids AS options_ids11, t0.image_ids AS image_ids12, t0.product_id AS product_id13 FROM Combination t0 WHERE t0.product_id = ? [25] []
[2015-11-09 09:26:58] doctrine.DEBUG: SELECT t0.id AS id1, t0.id_cat_dist AS id_cat_dist2, t0.name AS name3, t0.active AS active4, t0.maj_auto AS maj_auto5, t0.erasable AS erasable6, t0.ids_products AS ids_products7, t0.url_cat AS url_cat8 FROM Category t0 INNER JOIN product_category ON t0.id = product_category.category_id WHERE product_category.product_id = ? [31] []
[2015-11-09 09:26:58] doctrine.DEBUG: SELECT t0.id AS id1, t0.supplier_reference AS supplier_reference2, t0.price AS price3, t0.weight AS weight4, t0.colisage AS colisage5, t0.in_catalog AS in_catalog6, t0.product_id AS product_id7, t0.supplier_id AS supplier_id8 FROM ProductSupplier t0 WHERE t0.product_id = ? [31] []

这 6 分钟直到我收到严重错误消息:

[2015-11-09 09:32:02] php.CRITICAL: Fatal Error: Maximum execution time of 300 seconds exceeded {"type":1,"file":"/Applications/MAMP/htdocs/Symfony/vendor/jms/serializer/src/JMS/Serializer/GenericSerializationVisitor.php","line":127,"level":-1,"stack":[]} []
[2015-11-09 09:32:02] request.CRITICAL: Uncaught PHP Exception Symfony\Component\Debug\Exception\FatalErrorException: "Error: Maximum execution time of 300 seconds exceeded" at /Applications/MAMP/htdocs/Symfony/vendor/jms/serializer/src/JMS/Serializer/GenericSerializationVisitor.php line 127 {"exception":"[object] (Symfony\\Component\\Debug\\Exception\\FatalErrorException(code: 0): Error: Maximum execution time of 300 seconds exceeded at /Applications/MAMP/htdocs/Symfony/vendor/jms/serializer/src/JMS/Serializer/GenericSerializationVisitor.php:127)"} []

提前感谢您的帮助

更新:我终于明白了这个问题。正如 wilt 告诉我的,实体是完全加载的,并且因为每个类别都与产品和产品类别相关,所以每次都会加载很多实体。

一个解决方案是把一些 jmsserialzer 注释,特别是 maxdepth(1) 到加入的实体,并在相关实体上指定一个排除状态,它现在可以正常工作了。

【问题讨论】:

  • 如果我是对的,如果你接受我的回答,那就太好了......

标签: symfony doctrine-orm doctrine fosrestbundle jmsserializerbundle


【解决方案1】:

from the doctrine documentation:

在许多情况下,实体之间的关联会变得非常大。即使在像博客这样的简单场景中。在可以评论帖子的地方,您总是必须假设一个帖子吸引了数百个 cmets。在 Doctrine 2.0 中,如果您访问一个关联,它总是会完全加载到内存中。如果您的关联包含数百或数千个实体,这可能会导致非常严重的性能问题。

因此,如果您更新 ManyToMany 关系中的集合,Doctrine 将在执行任何 removeadd 操作之前将集合中的所有元素加载到内存中。

标记为fetch="EXTRA_LAZY" 在这里可能对您没有帮助(因为您可能还会删除操作)。

我能想到的最佳解决方案是将ManyToMany 关系拆分为OneToMany + ManyToOne 关联,其中一个名为ProductCategoryLink 的实体介于两者之间:

Product - ProductCategoryLink - Category

然后可以通过查找相应的ProductCategoryLink 来完成添加或删除操作,而无需解析数据库中的所有其他记录(您不想更改的记录)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-11
    • 1970-01-01
    • 2013-03-01
    • 1970-01-01
    • 2018-06-20
    • 1970-01-01
    • 1970-01-01
    • 2012-11-26
    相关资源
    最近更新 更多