mySQL-如何解释解释结果并优化此查询?
希望了解我的mySQL-如何解释解释结果并优化此查询?,mysql,optimization,query-optimization,explain,Mysql,Optimization,Query Optimization,Explain,希望了解我的EXPLAIN结果在这里的含义,并尽可能优化此查询和我的表 查询: SELECT i.pending, i.itemid, i.message, i.cid, i.dateadded, i.entrypoint, SUM(CASE WHEN v.direction = 1 THEN 1 WHEN v.direction = 2 THEN -1
EXPLAIN
结果在这里的含义,并尽可能优化此查询和我的表
查询:
SELECT i.pending,
i.itemid,
i.message,
i.cid,
i.dateadded,
i.entrypoint,
SUM(CASE WHEN v.direction = 1 THEN 1
WHEN v.direction = 2 THEN -1
ELSE 0 END) AS votes,
c.name AS cname,
c.tag AS ctag,
i.userid,
(SELECT COUNT(commentid) FROM `comments` WHERE comments.itemid = i.itemid) AS commentcount,
CASE WHEN NOT EXISTS (SELECT voteid FROM `votes` WHERE votes.itemid = i.itemid AND votes.userid = @userid) THEN '0' ELSE '1' END AS hasVoted,
CASE WHEN NOT EXISTS (SELECT voteid FROM `user_favorites` WHERE user_favorites.itemid = i.itemid AND user_favorites.userid = @userid) THEN '0' ELSE '1' END AS isFavorite
FROM `contentitems` i
LEFT JOIN votes v ON i.itemid = v.itemid
LEFT JOIN `user_favorites` uv ON i.itemid = uv.itemid AND (uv.userid = @userid)
INNER JOIN `categories` c ON i.cid = c.cid
GROUP BY i.itemid
HAVING SUM(CASE WHEN v.direction = 1 THEN 1
WHEN v.direction = 2 THEN -1
ELSE 0 END) > -3 AND i.pending = 0
ORDER BY i.dateadded DESC
(编辑格式)
结果如下:
+----+--------------------+----------------+--------+-------------------------+-------------------------+---------+------------------------+------+-------------------------------------------------------
| id | select_type | table | type | possible_keys key | key_len | ref | rows | Extra |
+----+--------------------+----------------+--------+-------------------------+-------------------------+---------+------------------------+------+------------------------------------------------------+
| 1 | PRIMARY | i | ALL | NULL | NULL | NULL | NULL | 121 | Using temporary; Using filesort |
| 1 | PRIMARY | v | ref | fk_contentitemsitemid_votesitemid | fk_contentitemsitemid_votesitemid | 4 | db33481_mydb.i.itemid | 2 | |
| 1 | PRIMARY | uv | ALL | NULL | NULL | NULL | NULL | 7 | |
| 1 | PRIMARY | c | eq_ref | PRIMARY | PRIMARY | 4 | db33481_mydb.i.cid | 1 | |
| 4 | DEPENDENT SUBQUERY | user_favorites | ALL | NULL | NULL | NULL | NULL | 7 | Using where |
| 3 | DEPENDENT SUBQUERY | votes | ref | fk_contentitemsitemid_votesitemid | fk_contentitemsitemid_votesitemid | 4 | func | 2 | Using where |
| 2 | DEPENDENT SUBQUERY | comments | ALL | NULL | NULL | NULL | NULL | 26 | Using where |
+----+--------------------+----------------+--------+-------------------------+-------------------------+---------+------------------------+------+------------------------------------------------------+
我发现没有用于访问
评论
、投票
和用户收藏夹
的键。除非表非常小,否则您应该尝试在这些表中的userid
和itemid
上添加索引。尝试查看此以了解解释计划。试着往下看,它清楚地解释了你需要寻找什么
你的解释计划越详细,信息就越少。请尝试使用oracle提供的。它是开源的,并为您提供了解释计划的适当细节 我将添加以下索引:
ALTER TABLE comments ADD INDEX(commentid)
altertableuser\u收藏夹添加索引(itemid,voteid)
此外,如果可能的_keys列表示NULL,则表示该表没有可用的键。即使它们没有用于优化,如果它们存在于查询中的某个列中,也会显示在那里。最可能的情况是,您在查询中未访问的列上的这些表上有一个主键。首先,您有一个select not exists投票ID,然后在from中进行左联接,最后在having中进行求和。这三次击中了你的投票表。如果每个投票可能与一个“ItemID”关联,那么最好将其自身作为自己的“总和”进行一次预聚合 此外,由于您的最后一个“HAVING”子句是投票的直接基础,所以在投票上使用左连接将成为一个死点,并最终以正常连接结束 尽管如此,我还是会先预先查询投票结果,然后加入到内容项和其他加入中。。。对用户\u收藏夹的查询是一个计数,将为0(未找到)或1(已找到)。不需要一个案例/当 我的第一个查询别名“PQ”表示“预查询” 其他人也表示需要索引,表示同意。我将确保每个表在用户ID或项目ID(或在适当的情况下两者)上都有各自的索引
其他几点。。。您最初开始查询所有ContentItems,但保留了与投票的连接。。。但随后应用了用户ID的元素。这无疑是对特定用户的查询。这就是说,我还将使用用户ID所做的任何事情的唯一项ID来预先启动整个查询。。。然后继续查询。我对您提到的三个表有一个主键,如何告诉查询使用它们?或者我应该在每个表上创建一个复合键,并相应地包含primary和userid/itemid?尝试创建一个复合键。在“')、1、0)附近出现语法错误,您可以更新您的答案吗?
SELECT
PQ.ItemID,
PQ.VSum as Votes,
PQ.HasVoted,
i.pending,
i.itemid,
i.message,
i.cid,
i.dateadded,
i.entrypoint,
i.userid,
c.name AS cname,
c.tag AS ctag,
( SELECT COUNT(commentid)
FROM `comments`
WHERE comments.itemid = PQ.itemid) AS commentcount,
( SELECT COUNT(*) FROM user_favorites uf
WHERE uf.itemid = PQ.itemid
AND uf.userid = @userid ) AS isFavorite
from
( SELECT
v.itemid,
SUM( case when v.Direction = 1 then 1
when v.Direction = 2 then -1
ELSE 0 end ) as VSum,
MAX( if( votes.userid = @userid, 1, 0 ) AS HasVoted
from
votes v
group by
v.itemid
having
VSum > -3 ) PQ
JOIN ContentItems i
ON PQ.ItemID = i.ItemID
and i.Pending = 0
JOIN Categories c
ON i.cid = c.cid
ORDER BY
i.dateadded DESC