更快地执行此SQL查询的方法

时间:2015-03-07 05:35:09

标签: php mysql sql optimization innodb

我有一个大型SQL表,用于存储用户添加到其个人资料中的已添加项目ID以及他们为其提供的评级。问题是,我需要快速计算项目被添加的次数,并且还需要获得给出的总评级。有时,评级可能为空,也可能不为空,具体取决于用户是否对该项目进行了评级。该表看起来像这样

Item_Feedback_ID (Pri, AI)  Item ID    Item Rating    User_ID_Added
     1                        5          Null               4
     2                        5           8                 5         
     3                        6           9                 9 

我需要为每个唯一的商品ID执行此操作(我已经有一个存储唯一商品ID的表)。我现在正在做的是:

PSEUDO PHP CODE:
$result = the result of: "SELECT item_id FROM items";
foreach ($item_id in $result) {
    $sql = "SELECT COUNT(item_id) as sum, SUM(`Item Rating`) as total_rating FROM 
            item_feedback WHERE item_id = $item_id";
//Run that sql statement in PHP and parse it and save in an array
}

有更有效的方法吗?似乎我浪费了很多时间,因为COUNT已经扫描了所有列,我必须再次为x个项目ID执行此操作。

4 个答案:

答案 0 :(得分:2)

您应该能够使用可选数据的子查询来完成这一个查询。我使用LEFT JOIN来获取额外数据,以便仍然可以返回不具有该数据的项目。子查询的原因是因为您正在使用COUNT。如果没有子查询,那将计算所有记录,而不仅仅是有反馈的记录。

SELECT 
  items.item_id,
  feedback.sum,
  feedback.total_rating
FROM items
LEFT JOIN(
  SELECT
    item_id,
    COUNT(item_id) as sum,
    SUM(`Item Rating`) as total_rating
    FROM item_feedback
    GROUP BY item_id
) AS feedback ON feedback.item_id = items.item_id

答案 1 :(得分:0)

$sql = "SELECT ifnull(t.count, 0) as count, 
               ifnull(t.total_rating, 0) total_rating, 
               a.item_id 
        FROM items a
        left join (SELECT COUNT(item_id) as count,
                          SUM(`Item Rating`) as total_rating,
                          b.item_id  
                     from item_feedback b
                     group by b.item_id) t on t.item_id = a.item_id " ;

答案 2 :(得分:0)

我不是PHP专家,但也许您可以将数据放入临时表中然后循环遍历它。也许你的SQL脚本就是这样的。

INSERT INTO TempTable
SELECT 
    COUNT(item_id) as sum, 
    SUM(`Item Rating`) as total_rating 
FROM item_feedback
GROUP BY item_id

然后通过item_id

循环您的TempTable

答案 3 :(得分:0)

如果您不需要为每个项目添加一行,那么只需查询item_feedback即可,并且使用SQL CASE语句也可以帮助您:

select 
item_id,
count(*) as item_added_count,
sum(case when [item rating] is not null then 1 else 0 end) as rating_count
from item_feedback
group by item_id

如果您确实需要为每个项目添加一行,并且想要在项目从未添加到item_feedback表时显示0,那么请使用带有items表的LEFT OUTER JOIN

select 
i.item_id,
sum(case when f.item_id is not null then 1 else 0 end) as item_added_count,
sum(case when f.[item rating] is not null then 1 else 0 end) as rating_count
from items i
left outer join item_feedback f on f.item_id = i.item_id
group by i.item_id