2014-05-15 4 views
0

내 웹 사이트의 세부 정보와 함께 이미지를 표시하고 있지만 늦게 사이트를로드하는 데 시간이 매우 많이 걸립니다.효율적인 Foreach 루프 쿼리 데이터베이스

가장 중요한 것은 격자에서 100 개의 게시물을 표시하는 데 100 번 반복되는 foreach 루프입니다. 실행할 때까지 14 초 걸린다

foreach($posts as $post) { 

      $hashtags[] = $this->HashTagsModel->get_hashtags($post["id"]); 
      $author[] = $this->UserModel->get_user_details($post["user_id"]); 
      $comment_count[] = $this->CommentModel->get_comments_count($post["id"]); 
      $is_favourited[] = $this->FavouriteModel->is_favourited($post["id"]); 
      $is_reposted[] = $this->RepostModel->is_reposted($post["id"]); 
      $vote_status[] = $this->vote_status($post["id"]); 
      $comments[] = $this->count_comments($post["id"]); 

     } 

더 효율적으로하기 위해 어떻게 다르게 할 수 있습니까? 우리의 웹 사이트 데이터베이스가 어떤 도움을 주시면 감사하겠습니다

대규모되기 전에이,

관련, 거의

+1

글쎄, 만약 당신이 이미 성장하는 데이터베이스가 원인이라고 생각한다면 (아마도 바로 거기에있을 것입니다.), PHP 레벨에서이 문제를 해결할 수 없습니다. SQL 문, 테이블, 특히 데이터베이스 내의 인덱스 정의를 면밀히 관찰해야합니다! 따라서 우리가 데이터베이스 구조와 쿼리를 게시 할 수 있도록 도와주십시오. – arkascha

+0

7 개의 (+) 하위 쿼리가 포함 된 100 개의 게시물은 시간이 오래 걸리지 않아야합니다. 나는이 7 가지 기능 1의 실행 시간을 확인해보기를 권합니다. 그 중 하나가 대부분의 시간 문제를 일으킬 것입니다. –

답변

2

루프 쿼리 데이터베이스를 foreach는 할 수있는 효율적인 방법이 아니다 foreach는 쿼리 데이터베이스하다 해고

을했다. 이는 알 수없는 양의 쿼리를 실행 중지하여 대규모 대기열을 생성 할 수 있기 때문입니다. 갑자기 5000 개의 이미지가 추가되면 어떻게 되나요? 이 쿼리는 매우 오랜 시간이 걸릴 것입니다.

당신은 같은 $ 포스트 [ "ID"]이 당신의 위치를 ​​변수는 포스트 IDS,이 같은 배열 수립 후 단일 쿼리를 수행하여 현저하게이 과정을 줄일 수 있도록 내가 가정입니다 :

$postids = array(); 
foreach($posts as $post) { 
    $postids[] = $post['id']; 
} 

// Selecting from 1 table 
$query = 'SELECT * FROM hashtags WHERE id IN ('. implode(",", $postids) .')'; 

id가 귀하의 postid 중 하나 인 해시 태그에 대한 모든 정보를 가져옵니다. 즉, 내가 일반적인 될거야 데이터베이스 구조를 알지 못하고, 여러 가져올 가능성이 원하는 것, 단 1 표, 그래서 뭔가 같은 :

// Selecting and joining data from multiple tables 
$query = ' SELECT author.name, table.col FROM posts 
LEFT JOIN author ON author.id = post.author_id 
LEFT JOIN table ON table.id = post.table_id 
WHERE posts.id IN IN ('. implode(",", $postids) .')'; 

그것은 더 정확성이 될 수있는 좀 더 어렵습니다. 나는 테이블을 조인하면 더 나은 결과를 얻을 수 있다고 생각합니다. 투표/의견 수를 합칠 수도 있습니다. 그렇게 할 수 없다면 게시물과 관련된 모든 데이터를 쿼리 한 다음 PHP로 공식화하면 쿼리의 개수를 정확히 알 수 있습니다. 예를 들어, 단일 포스트 ID 대신 배열을 허용하도록 모델을 변경 한 다음 변경하려면 "WHERE post_id를 = X"에서 "WHERE IN post_id를 (x)는"다음과 같이 수행 할 수 있습니다

$postids = array(); 
foreach($posts as $post) { 
    $postids[] = $post['id']; 
} 

$hashtags = $this->HashTagsModel->get_hashtags($postids); 
$author = $this->UserModel->get_user_details($postids); 
$comment_count = $this->CommentModel->get_comments_count($postids); 
$is_favourited = $this->FavouriteModel->is_favourited($postids); 
$is_reposted = $this->RepostModel->is_reposted($postids); 
$vote_status = $this->vote_status($postids); 
$comments = $this->count_comments($postids); 

이를 루프 외부에서 쿼리를 가져오고 쿼리가 아닌 7 개의 SQL 쿼리 만있을 것입니다. PHP에서는 각 배열의 결과를 반복하여 각 배열의 ID를 기반으로 게시물에 다시 할당합니다.

+0

와우 정말 도움이됩니다! 그러나 나는 당신의 마지막 제안을 할 것이지만 몇 가지 문제가 있습니다. 저자의 경우 저자가 만든 게시물의 인스턴스 하나만 반환합니다. 예를 들어 저자 'B'는 3 개의 게시물을 만들었지 만 한 번 반환하고 주문을 채우는 것입니까? 이 작업을 수행하는 방법에 대한 제안 사항은 무엇입니까? –

+0

모델이 어떻게 작동하는지, 그리고 무엇을 달성하려고하는지 알지 못하면 명확한 그림을 얻는 것이 어렵습니다. [1, 3, 4, 4, 10]와 같이 5 개의 게시물 ID가있는 경우 get_user_details에 전달하면 게시물 ID가 고유 한 위치에서만 각 결과를 찾습니다. id 4는 한 번만 반환됩니다.논리적으로는 순서에 대해 많은 부분에 대해 중요하지 않습니다. 결과를 반복하고 다른 데이터에 데이터를 추가하면됩니다. 왜 하나의 게시물에 대해 그 단일 게시물의 작성자가 다른 3 개의 게시물을 작성했는지 알아야 할 필요가 있는지 궁금합니다. – viion