2015-02-05 3 views
1

나는 매우 기본적이고 간단 InstagramTag라는 단체가 있습니다최적화

class InstagramTag 
{ 
    /** 
    * @var integer $id 
    * 
    * @ORM\Column(name="id", type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    protected $id; 

    /** 
    * @var string 
    * @ORM\Column(name="tag", type="string", nullable=true) 
    */ 
    protected $tag; 

    /** 
    * 
    * @ORM\OneToMany(targetEntity="App\MainBundle\Entity\InstagramPictureTag", mappedBy="tag") 
    */ 
    protected $picturetag; 


    /** 
    * Get id 
    * 
    * @return integer 
    */ 
    public function getId() 
    { 
     return $this->id; 
    } 

    /** 
    * Get tag 
    * 
    * @return string 
    */ 
    public function getTag() 
    { 
     return $this->tag; 
    } 

    /** 
    * Set tag 
    * 
    * @param string $tag 
    * @return InstagramTag 
    */ 
    public function setTag($tag) 
    { 
     $this->tag = $tag; 
     return $this; 
    } 

} 

와 나는 기본적으로 특정 태그가 이미 존재로 InstagramTag 있는지 확인이 루틴이 아닙니다. 존재하지 않는 경우 하나를 만드는, 그래서 코드는 다음과 같습니다

foreach ($image->tags as $tag) { 
     $existingTag = $this->em->getRepository('AppMainBundle:InstagramTag')->findOneByTag($tag); 
     $instaPictureTag = new InstagramPictureTag(); 
     $instaPictureTag->setPicture($instaShopPicture); 

     if ($existingTag) { 
      $instaPictureTag->setTag($existingTag); 
     } else { 
      $instagramTag = new InstagramTag(); 
      $instagramTag->setTag($tag); 
      $this->em->persist($instagramTag); 
      $instaPictureTag->setTag($instagramTag); 
     }  

     $this->em->persist($instaPictureTag);    
    } 

코드가 InstagramTag 테이블이 160 만 개 항목이기 때문에 상대적으로 느립니다. 따라서 1 태그 만 검색하면 MySQL 테이블에서 약 1.3 초가 걸립니다.

답변

0

귀하의 경우에는 MySQL 병 목으로 보입니다. 그래서 내가 충고하는 것은 foreach 루프 내부에 태그가 있는지 확인하지 않는 것입니다. 루프를 반복 할 때마다 mySql을 쿼리하기 때문입니다.

대신 나는 당신이 InstagramTag 개체의 집합을 얻을이 방법

public function getRowsByTags(array $tags) 
{ 
    return $this->createQueryBuilder('i') 
      ->andWhere('i.tag IN (:tags)') 
      ->setParameter(':tags', $tags) 
      ->getQuery() 
      ->execute(); 
} 

(그래서 당신은 한 번만 mySQL 전화) 한 번에 모든 태그에 대한 개체를 찾을 수 custom repository 방법을 만들 것입니다. 그런 다음 foreach 루프 내부에서이 컬렉션을 반복해야합니다 (느린 mysql을 건드리지 않고 메모리에서 반복). InstagramTag이 있는지 확인하십시오. 그렇지 않은 경우 새 것을 만들어야합니다.

tag 열이 mysql에서 제대로 인덱싱 된 경우 다른 질문이 있습니다. 이는 매우 느리기 때문에 여기에있는 질문입니다.

+0

마지막 줄이 실제 답변입니다. 태그를 색인화하십시오. 160 만개의 기록은 적절히 색인 될 때 ​​사소한 것입니다. IN 절을 사용하는 것은 좋은 생각이지만 인덱싱이 핵심입니다. http://doctrine-orm.readthedocs.org/en/latest/reference/annotations-reference.html#annref-index – Cerad