I have a query to check how many unique votes each photo has in a photo contest. In my Votes.php model I have this query, which for 200 photos is taking around 15 minutes to complete:
public function getVotes()
{
$itemsTable = new Photocontest_Model_Photos();
$items=$itemsTable->fetchAll();
$itemsArr=array();
// get votes per item
for($i=0; $i<count($items); $i++){
$select = $this->select(Zend_Db_Table::SELECT_WITH_FROM_PART);
$select->setIntegrityCheck(false)
->from(array('v' => $this->_name), array('*', 'COUNT(*) AS total_overall_votes'))
->where('v.item_id = ?', $items[$i]['id'])
->group('v.user_env')
;
$votes=$this->fetchAll($select);
$votes=$votes->toArray();
$ratingTotal=0;
foreach($votes AS $vote){
$itemsArr[$items[$i]['id']]['total_overall_votes']=$vote['total_overall_votes']; // including dups(cheaters)
$itemsArr[$items[$i]['id']]['total_item_votes']=count($votes);
$itemsArr[$items[$i]['id']][$vote['rating']]=$this->getVotesPerRating($vote['item_id'], $vote['rating']);
$ratingTotal+=$vote['rating']; // total rating (stars)
}
if($itemsArr[$items[$i]['id']]['total_item_votes']<1){
$itemsArr[$items[$i]['id']]['total_item_votes']=0;
}
$itemsArr[$items[$i]['id']]['id']=$items[$i]['id'];
$itemsArr[$items[$i]['id']]['title']=$items[$i]['title'];
$itemsArr[$items[$i]['id']]['largefile']=$items[$i]['largefile'];
$itemsArr[$items[$i]['id']]['thumbfile']=$items[$i]['thumbfile'];
$itemsArr[$items[$i]['id']]['created']=$items[$i]['created'];
$itemsArr[$items[$i]['id']]['rating_total']=$ratingTotal;
$itemsArr[$items[$i]['id']]['rating_average']=$ratingTotal/5;
}
$itemsArr=$this->itemSort($itemsArr);
return $itemsArr;
}
public function itemSort($itemArr, $sortBy, $direction){
$tempArr=array();
foreach($itemArr AS $key => $value){
$rating_average[$key]=$value['rating_average'];
$total_item_votes[$key]=$value['total_item_votes'];
}
array_multisort($rating_average, SORT_DESC, $total_item_votes, SORT_DESC, $itemArr);
return $itemArr;
}
public function getVotesPerRating($item_id, $rating)
{
$select = $this->select(Zend_Db_Table::SELECT_WITH_FROM_PART);
$select->setIntegrityCheck(false)
->from(array('v' => $this->_name), array('count(*) AS total'))
->where('v.item_id = ?', $item_id)
->where('v.rating = ?', $rating)
->group('v.user_env')
;
$votes= $this->fetchAll($select);
$total= count($votes);
return $total;
}
The user_env that I'm using in the "group" part of the query has data similar to this: a:2:{s:2:"ip";s:14:"174.50.113.117";s:10:"user_agent";s:113:"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.18) Gecko/2010020220 Firefox/3.0.18 (.NET CLR 3.5.30729)";}