2010-01-26 5 views
0

이 코드의 목표는 모든 상점의 모든 브랜드를 하나의 배열로 가져와이를 화면에 출력하는 것입니다. 브랜드가 여러 매장에있는 경우 한 번만 추가됩니다.성능 향상을 위해이 PHP 코드를 단순화 할 수 있습니까?

하지만 루프가 너무 많아 트래픽이 많을 때 CPU를 막을 수 있다고 생각합니다. 더 좋은 해결책이 있습니까?

function getBrands($stores, $bl) 
    { 
    $html = ""; 

    //Loop through all the stores and get the brands 
    foreach ($stores as $store) 
    { 
     //Get all associated brands for store 
     $result = $bl->getBrandsByStore($store['id']); 

     //Add all brands to array $brands[] 
     while ($row = mysql_fetch_array($result)) 
     { 
     //If this is the first run, we do not need to check if it already exists in array 
     if(sizeof($brands) == 0) 
     { 
      $brands[] = array("id" => $row['id'], "name" => $row['name']); 
     } 
     else 
     { 
      // Check tosee if brand has already been added. 
      if(!isValueInArray($brands, $row['id'])) 
      $brands[] = array("id" => $row['id'], "name" => $row['name']); 
     } 
     } 
    } 

    //Create the HTML output 
    foreach($brands as $brand) 
    { 
     $url = get_bloginfo('url').'/search?brandID='.$brand['id'].'&brand='.urlSanitize($brand['name']); 
     $html.= '<a href="'.$url.'" id="'.$brand['id'].'" target="_self">'.$brand['name'].'</a>, '; 
    } 

    return $html; 
    } 

    //Check to see if an ID already exists in the array 
    function isValueInArray($values, $val2) 
    { 
    foreach($values as $val1) 
    { 
     if($val1['id'] == $val2) 
     return true; 
    } 
    return false; 
    } 
+0

데이터베이스 테이블과 실행중인 쿼리에 대해 자세히 알려 줄 수 있습니까? 하나의 데이터베이스 쿼리와 올바른 조인을 사용하는 하나의 루프로 줄일 수있는 좋은 기회가 있습니다. –

답변

1

테이블은 어떻게 설계 되었습니까? 상점 테이블, 브랜드 테이블 및 상점과 브랜드 간 관계가있는 링크 테이블이있는 경우, 하나의 쿼리에서 브랜드 테이블의 브랜드 목록을 가져 와서 다른 로직을 수행 할 필요가 없습니다.

테이블을 디자인하면 질문해야하는 질문에 쉽게 답할 수 있습니다.

+0

DB가 올바르게 설계되었습니다. 그것은 shoping 가이드 테이블을 포함해야하기 때문에 complicatd 쿼리가 될 것입니다. 가이드 테이블에는 x 개의 점포가 있고 각 상점에는 y 개의 브랜드가 있습니다. – Steven

1

특정 상점 세트에 대해 모든 브랜드를 가져와야하는 경우, 모든 상점을 반복하고 별도의 정보를 얻는 대신 해당 작업을 수행하기 위해 작성된 조회를 사용해야합니다.

2

두 세트의 배열을 반복 할 필요가 없습니다 (하나는 브랜드 배열을 구축하고 하나는 HTML을 만들기 위해 필요합니다). 특히 도우미 함수가 루프를 통과하기 때문에 array_key_exists 함수를 사용하고 ID를 키로 사용하십시오. 또한 implode 함수를 사용하여 ','링크를 결합 할 수 있으므로 수동으로 수행 할 필요가 없습니다. 기존 코드에서 쉼표를 사용하지 않아도됩니다. for 루프를 두 세트 사용하지 않고이 작업을 수행 할 수 있습니다.

function getBrands($stores, $bl) 
{ 
    $brands = array(); 

    //Loop through all the stores and get the brands 
    foreach ($stores as $store) 
    { 
     //Get all associated brands for store 
     $result = $bl->getBrandsByStore($store['id']); 

     //Add all brands to array $brands[] 
     while ($row = mysql_fetch_array($result)) 
     { 
      if (!array_key_exists($row['id']) 
      { 

       $url = get_bloginfo('url') . '/searchbrandID=' . 
         $brand['id'] . '&brand=' . urlSanitize($brand['name']); 
       $brands[$row['id']] .= '<a href="' . $url . '" id="' . 
             $brand['id'] . '" target="_self">' . 
             $brand['name'] . '</a>'; 
      } 
     } 
    } 

    return implode(', ', $html); 
} 

이렇게하면 동일한 효과가 조금 더 빨라집니다. 루프백을 통해 브랜드를 얻은 다음 HTML을 반복하여 작성하기 때문에 더 빨라질 것입니다. 별도의 두 루프로 처리 할 필요가 없으므로 한 번에 모두 HTML을 저장하면됩니다. 또한 array_key_exists을 사용하기로 전환했기 때문에 도우미 대신 브랜드가 있는지 확인하기 위해 다시 반복하여 검사를 작성했지만 속도가 향상됩니다. Hashmaps는 해시 맵의 각 요소에 키가 있고 키가 있는지 확인하는 네이티브 함수가 있기 때문에 멋지다.

foreach 내부에서 작업 할 필요가 없도록 별개의 필터로 더 나은 SQL 문을 작성하여 작업을 최적화 할 수 있습니다.

+0

해시지도로 이동하십시오! 당신은 정말로 그에게 설명하지 않습니다 ** ** 왜 ** 더 빠르지 만 ... –

+0

더 나은 설명, 감사합니다. – Parrots

4

귀하의 의견에서 "가이드 테이블에는 X 개의 점포가 있고 각 상점에는 Y 개의 브랜드가 있습니다."라고 말합니다. 아마도 store-id와 brand_id를 하나의 상점 대 다수 브랜드 관계로 묶는 "상점"테이블, "브랜드"테이블 및 "링크"테이블이있을 것입니다.

때문에, 하나의 SQL 쿼리가 작업을 할 수있는 경우 : 최종 GROUP BY 절은 한 번만 각 브랜드를 보여줄 것이다

SELECT b.`id`, b.`name` 
FROM `stores` s 
LEFT JOIN `linkage` l 
    ON l.`store`=s.`id` 
LEFT JOIN `brands` b 
    ON b.`id`=l.`brand` 
GROUP BY b.`id`; 

. 제거하면 상점 ID를 추가하고 상점 간 연관의 전체 목록을 출력 할 수 있습니다.

+0

SQL이 완전히 정확한지는 모르겠지만 SQL 쿼리에 로직을 옮기는 최선의 방법입니다. 이것은 가장 빠른 솔루션입니다! – powtac

관련 문제