[英]mySQL - How can I interpret my EXPLAIN results and optimize this query?
想要了解我的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 |
+----+--------------------+----------------+--------+-------------------------+-------------------------+---------+------------------------+------+------------------------------------------------------+
首先,你有一個選擇不存在的投票ID,然后在from中進行左連接,最后在有一個和。 這是你的投票表3次。 如果每個投票可能與單個“ItemID”相關聯,那么最好將其自身預先匯總為其自己的“Sum”完成ONCE。
此外,由於你的最終“HAVING”條款是投票的直接基礎,因此在投票上進行左連接將成為一個死點並最終以正常的JOIN結束。
所有這一切,我會預先查詢FIRST與預先確定合格的HAVING條件的FINISH,然后加入內容項和其他聯接...對User_Favorites的查詢是一個計數,將為0(不是發現),或1(找到)。 不需要案件/什么時候
我的第一個查詢別名“PQ”代表“PreQuery”
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
其他人已表示需要索引,同意。 我會確保每個表都有關於用戶ID或項ID的相應索引(或兩者都適當)。
結合其他點...你最初開始查詢查詢所有ContentItems,但是左邊加入投票...但是然后應用用戶ID的元素。 這絕對是特定用戶查詢的氣味。 話雖這么說,我會額外預先啟動整個查詢,只選擇一個ItemID,用戶ID已經做了什么...然后繼續查詢。
我看到沒有用於訪問comments
, votes
和user_favorites
。 除非表格非常小,否則您應該嘗試在這些表格中的userid
和itemid
上添加索引。
嘗試查看此鏈接以了解解釋計划。 嘗試下去那一節,它清楚地解釋了你需要尋找什么。
更多關於你的解釋計划看起來更少的信息。 請嘗試從oracle使用sql developer 。 它是開源的,並且確實為您提供有關解釋計划的詳細信息。
我會添加以下索引:
ALTER TABLE comments ADD INDEX (commentid)
ALTER TABLE user_favorites ADD INDEX (itemid, voteid)
此外,如果possible_keys列顯示NULL,則表示該表沒有可用的鍵。 即使它們不用於優化,如果它們存在於查詢中的列中,它們也會顯示在那里。 最有可能的是,您在查詢中未訪問的列上的那些表上有一個主鍵。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.