我有这个查询(下面),虽然它确实有效我想知道它是否是最好的,因为它将对数千条记录。我会尝试尽力解释。
SELECT items.*,
p.file AS item_pic,
i_f.id AS favorite_id,
COALESCE(f.favorite_count, 0) AS favorite_count,
COALESCE(b.num_buys, 0) AS num_buys,
COALESCE(c.comment_count, 0) AS comment_count
FROM items i
INNER JOIN (SELECT file,
item_id
FROM item_pics
ORDER BY item_pics.id ASC) AS p
ON p.item_id = i.id
LEFT JOIN (SELECT COUNT(*) AS favorite_count,
item_id
FROM item_favorites
GROUP BY item_id) AS f
ON f.item_id = i.id
LEFT JOIN (SELECT COUNT(*) AS num_buys,
item_id
FROM purchases
GROUP BY item_id) AS b
ON b.item_id = i.id
LEFT JOIN (SELECT COUNT(*) AS comment_count,
item_id
FROM comments
GROUP BY item_id) AS c
ON c.item_id = i.id
LEFT JOIN item_favorites AS i_f
ON i.id = i_f.item_id
AND i_f.userid = '14'
GROUP BY i.id
LIMIT 0, 20
所以我们选择数据库中的项目。第一个连接用于图片(项目有多张图片,但我只想要一张)。
下次加入是收藏计数。每次用户收藏某些内容时,它会将其添加到带有一些信息的表格收藏夹中,因此我只想获取该项目的收藏夹总数。
接下来是此商品的购买数量。与收藏夹几乎相同。
之后是评论。再次,这就像购买和收藏计数一样。
最后一次加入是查看登录用户(id 14)是否已收藏此项,否则我使用COALESCE返回0。
就像我说这一切都能正常工作但是在购买表中加载大约6700个项目和大约180K行的表需要几秒钟,一次只能加载20个(我做滚动/加载类似于Facebook的/ Twitter等)。已在所有表上正确设置索引。一旦完成/正确,我想知道如何限制过去七天的购买结果,并按购买次数(num_buys)订购。
编辑:EXPLAIN的结果
答案 0 :(得分:0)
我想你想要第一张照片(最低身份证),并且需要照片,其他一切都是可选的。
我猜你正在做子查询,因为你认为加入不相关的子查询(只连接一次连接表)会比相关的子查询或普通的JOIN更快。但是,您最终必须两次查找记录,第二次查找(对于实际连接)不会使用索引,因为派生(临时表)没有索引。
尝试正常的JOIN:
SELECT items.*,
p.file AS item_pic,
COALESCE(i_f.id, 0) AS favorite_id,
COUNT(f.item_id) AS favorite_count,
COUNT(b.item_id) AS num_buys,
COUNT(c.item_id) AS comment_count
FROM items i
STRAIGHT_JOIN item_pics p
ON p.item_id = i.id
LEFT JOIN item_pics p2
ON p2.item_id = i.id
AND p2.id < p1.id
LEFT JOIN item_favorites f
ON f.item_id = i.id
LEFT JOIN purchases b
ON b.item_id = i.id
LEFT JOIN comments c
ON c.item_id = i.id
LEFT JOIN item_favorites AS i_f
ON i_f.item_id = i.id
AND i_f.userid = '14'
WHERE p2.id IS NULL
GROUP BY i.id
LIMIT 20
图片上的双重加入是反加入WHERE p2.id IS NULL
,用于检索具有最低id
的图片。