我得到了以下實體:symfony3逆實體映射慢
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
/**
* Productnum
*
* @ORM\Table(name="productnum")
* @ORM\Entity
*/
class Productnum
{
/**
* @var object
*
* @ORM\OneToMany(
* targetEntity="AppBundle\Entity\Products",
* mappedBy="productnum",
* cascade={"persist", "remove"}
*)
*/
protected $productnumInverse;
/**
* Constructor
*/
public function __construct()
{
$this->productnumInverse = new ArrayCollection();
}
/**
* Get productnumInverse
*
* @return Collection
*/
public function getProductnumInverse()
{
return $this->productnumInverse;
}
}
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
/**
* Products
*
* @ORM\Table(name="products")
* @ORM\Entity
*/
class Products
{
/**
* @var \AppBundle\Entity\Productnum
*
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\Productnum", inversedBy="productnumInverse")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="productnum_id", referencedColumnName="row_id")
* })
*/
public $productnum;
/**
* @var object
*
* @ORM\OneToMany(
* targetEntity="AppBundle\Entity\Product_region", fetch="EAGER",
* mappedBy="productid",
* cascade={"persist", "remove"}
*)
*/
protected $productInverse;
/**
* Constructor
*/
public function __construct()
{
$this->productInverse = new ArrayCollection();
}
}
<?php
namespace AppBundle\Entity;
use AppBundle\AppBundle;
use AppBundle\Entity\Productnum_filial;
use Doctrine\ORM\Mapping as ORM;
/**
* Productnum_region
*
* @ORM\Table(name="productnum_region")
* @ORM\Entity
*/
class Productnum_region
{
//regular getters and setters here...
}
和映射實體:
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Product_region
*
* @ORM\Table(name="product_region")
* @ORM\Entity
*/
class Product_region
{
/**
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @var \AppBundle\Entity\Products
*
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\Products")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="product_id", referencedColumnName="row_id")
* })
*
*/
private $productid;
/**
* @var \AppBundle\Entity\Productnum_region
*
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\Productnum_region")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="region_id", referencedColumnName="id")
* })
*/
private $regionid;
}
在我的控制,我得到了下面的代碼
$sql = sprintf("SELECT p FROM 'AppBundle:Productnum' p");
$productnums = $em->createQuery($sql)
->setFirstResult($start)
->setMaxResults($length)
->getResult();
$data = [];
foreach($productnums as $productnum) {
$prods = '';
foreach($productnum->getProductnumInverse() as $product) {
$filials = [];
$regions = [];
if($product && $product->getAllregions()){
$regions[] = $filials[] = 'All';
} elseif($product && $product->getAllfilials()){
$filials[] = 'All';
$regs = $product->getProductInverse();
foreach($regs as $reg){
$regions[] = $reg->getRegionid()->getName();
}
}elseif($product){
$regs = $product->getProductInverse();
foreach($regs as $reg){
$fil = $reg->getRegionid()->getFilial()->getName();
if(!in_array($fil, $filials)){
$filials[] = $fil;
}
$regions[] = $reg->getRegionid()->getName();
}
}
}
問題是在我的本地機器上這個代碼工作正常,但在遠程服務器上它工作得很慢。我在本地機器和服務器上都打開了Symfony分析器,並在我的本地機器上看到(這是確定的),它花費了336 DB(總共1.5秒)查詢來完成其中的大部分查詢,如下所示:
SELECT t0.id AS id_1, t0.name AS name_2, t0.code AS code_3, t0.filial_id AS filial_id_4 FROM productnum_region t0 WHERE t0.id = ?
Parameters: [0 => 100]
和
SELECT t0.row_id AS row_id_1, ... t0.productnum_id AS productnum_id_21, t22.id AS id_23, t22.product_id AS product_id_24, t22.region_id AS region_id_25 FROM products t0 LEFT JOIN product_region t22 ON t22.product_id = t0.row_id WHERE t0.productnum_id = ?
Parameters: [0 => 945]
而我的服務器上有總共36個查詢(20秒總,BAD),其中一個(並且可能是最慢的一個)中的溶液如下:
SELECT t0.row_id AS row_id_1, ... t0.productnum_id AS productnum_id_21, t22.id AS id_23, t22.product_id AS product_id_24, t22.region_id AS region_id_25
FROM products t0 LEFT JOIN product_region t22 ON t22.product_id = t0.row_id WHERE t0.row_id IN (?)
Parameters: [ 0 => [ 0 => 2, 1 => 97, 2 => 212, 3 => 225, 4 => 297, 5 => 355, 6 => 356, 7 => 482, 8 => 571, 9 => 737, 10 => 789
...MANY MANY MANY data here...
所以問題是怎麼會發生,不同的機器上的相同的代碼將轉換爲不同的查詢,以及如何可以避免這種情況?
謝謝
你是否開始使用相同環境的應用程序?(prod/dev) – svgrafov
我建議重新構思這個概念,因爲超過300個簡單計算的查詢肯定太多了。 – eRIZ
你好 - 我的回答是否有助於解決你的問題? –