2016-06-16 2 views
0

Код ниже - это сценарий для социальных сетей - это класс фида, проблема в том, что у гонораров много сообщений, а многие сторонники даже apresetnta гигантские медленно, кто-то может сказать мне если есть что-то не так с запросами и ниже сценарий, спасибоСценарий медленный, когда у вас много данных.

public function __construct($dbo = NULL) 
{ 
    parent::__construct($dbo); 
} 

public function count() 
{ 
    $count = 0; 

    $stmt = $this->db->prepare("SELECT * FROM profile_followers WHERE follower = (:followerId) ORDER BY create_at DESC"); 
    $stmt->bindParam(':followerId', $this->requestFrom, PDO::PARAM_INT); 

    if ($stmt->execute()) { 

     while ($row = $stmt->fetch()) { 

      $stmt2 = $this->db->prepare("SELECT count(*) FROM posts WHERE fromUserId = (:fromUserId) AND removeAt = 0 ORDER BY createAt DESC"); 
      $stmt2->bindParam(':fromUserId', $row['follow_to'], PDO::PARAM_INT); 
      $stmt2->execute(); 

      $count = $count + $stmt2->fetchColumn(); 
     } 
    } 

    return $count; 
} 

public function getMaxId() 
{ 
    $stmt = $this->db->prepare("SELECT MAX(id) FROM posts"); 
    $stmt->execute(); 

    return $number_of_rows = $stmt->fetchColumn(); 
} 

public function get($itemId = 0) 
{ 
    if ($itemId == 0) { 

     $itemId = $this->getMaxId(); 
     $itemId++; 
    } 

    $feed = array("error" => false, 
        "error_code" => ERROR_SUCCESS, 
        "itemId" => $itemId, 
        "items" => array()); 

    $stmt = $this->db->prepare("SELECT * FROM profile_followers WHERE follower = (:followerId) ORDER BY create_at DESC"); 
    $stmt->bindParam(':followerId', $this->requestFrom, PDO::PARAM_INT); 

    if ($stmt->execute()) { 

     $items = array(); 

     while ($row = $stmt->fetch()) { 

      $stmt2 = $this->db->prepare("SELECT id FROM posts WHERE fromUserId = (:fromUserId) AND id < (:itemId) AND removeAt = 0 ORDER BY id DESC"); 
      $stmt2->bindParam(':fromUserId', $row['follow_to'], PDO::PARAM_INT); 
      $stmt2->bindParam(':itemId', $itemId, PDO::PARAM_INT); 
      $stmt2->execute(); 

      while ($row2 = $stmt2->fetch()) { 

       $items[] = array("id" => $row2['id'], "itemId" => $row2['id']); 
      } 
     } 

     $stmt3 = $this->db->prepare("SELECT id FROM posts WHERE fromUserId = (:fromUserId) AND id < (:itemId) AND removeAt = 0 ORDER BY id DESC"); 
     $stmt3->bindParam(':fromUserId', $this->requestFrom, PDO::PARAM_INT); 
     $stmt3->bindParam(':itemId', $itemId, PDO::PARAM_INT); 
     $stmt3->execute(); 

     while ($row3 = $stmt3->fetch()) { 

      $items[] = array("id" => $row3['id'], "itemId" => $row3['id']); 
     } 

     $currentItem = 0; 
     $maxItem = 20; 

     if (count($items) != 0) { 

      arsort($items); 

      foreach ($items as $key => $value) { 

       if ($currentItem < $maxItem) { 

        $currentItem++; 

        $item = new post($this->db); 
        $item->setRequestFrom($this->requestFrom); 

        $itemInfo = $item->info($value['itemId']); 

        array_push($feed['items'], $itemInfo); 

        $feed['itemId'] = $itemInfo['id']; 

        unset($itemInfo); 
        unset($item); 
       } 
      } 
     } 
    } 

    return $feed; 
} 

public function setRequestFrom($requestFrom) 
{ 
    $this->requestFrom = $requestFrom; 
} 

public function getRequestFrom() 
{ 
    return $this->requestFrom; 
}` 
+0

SO не код обзора службы –

+0

Поинтересуйтесь на http://codereview.stackexchange.com/ – Ave

+0

Возможно, вам следует рассмотреть возможность использования одного запроса с JOIN –

ответ

1

несколько предложений в целом:

  • вместо «SELECT *», используйте «SELECT follow_to», так что это только column Вы используете
  • на том же заявлении, сортировка занимает много времени и не используется
  • нет необходимости выполнять новый запрос для каждого profile_follower
  • на внутреннем запросе, нет необходимости сортировать только для подсчета

Если есть 1000 подписчиков, вы сортируете сообщения 1000 раз без необходимости.

Вместо этого используйте один запрос и индексные сообщения в id и removeAt и index profile_followers on follower.

SELECT count(*) 
FROM posts p 
JOIN profile_followers pf ON p.fromUserId = pf.follow_to 
WHERE p.removeAt = 0 
AND  pf.follower = :followerId; 
Смежные вопросы