2013-07-13 35 views
0
SELECT 
    n.id, 
    n.title, 
    n.text, 
    n.date, 
    IFNULL(ap.name, a.name) AS name, 
    IFNULL(ap.path, a.path) AS path, 
    IFNULL(ap.extension, a.extension) AS extension, 
    IFNULL(ap.width, a.width) AS width, 
    IFNULL(ap.height, a.height) AS height, 
    IFNULL(ap.server, a.server) AS server, 
    s.id AS source_id, 
    s.name AS source_name 
FROM news n 
LEFT JOIN news_attachments na ON n.id = na.news_id AND na.cover = 1 
LEFT JOIN attachments a ON na.attachments_id = a.id 
LEFT JOIN attachments ap ON a.id = ap.parent AND ap.width = 136 
JOIN sources s ON n.sources_id = s.id 
WHERE n.moderate = 1 AND n.delete = 0 
GROUP BY n.id 
ORDER BY n.date DESC 
LIMIT 25 

我有這個SQL查詢。我有一個問題是否好?也許我可以改進它?優化我的長mysql查詢

在這部分

LEFT JOIN attachments a ON na.attachments_id = a.id 
LEFT JOIN attachments ap ON a.id = ap.parent AND ap.width = 136 

我加載圖像的預覽,然後選擇:

IFNULL(ap.name, a.name) AS name, 
    IFNULL(ap.path, a.path) AS path, 
    IFNULL(ap.extension, a.extension) AS extension, 
    IFNULL(ap.width, a.width) AS width, 
    IFNULL(ap.height, a.height) AS height, 
    IFNULL(ap.server, a.server) AS server 

這意味着,如果有圖像的預覽,然後使用它以其它方式使用原始圖像

說明:

+----+-------------+-------+--------+-------------------------------------------+----------------------+---------+--------------------------+------+---------------------------------+ 
| id | select_type | table | type | possible_keys        | key     | key_len | ref      | rows | Extra       | 
+----+-------------+-------+--------+-------------------------------------------+----------------------+---------+--------------------------+------+---------------------------------+ 
| 1 | SIMPLE  | s  | ALL | PRIMARY,id        | NULL     | NULL | NULL      | 4 | Using temporary; Using filesort | 
| 1 | SIMPLE  | n  | ref | fk_news_sources1_idx      | fk_news_sources1_idx | 4  | base.s.id    | 93 | Using where      | 
| 1 | SIMPLE  | na | ref | PRIMARY,fk_news_has_attachments_news1_idx | PRIMARY    | 4  | base.n.id    | 1 |         | 
| 1 | SIMPLE  | a  | eq_ref | PRIMARY,id        | PRIMARY    | 4  | base.na.attachments_id | 1 |         | 
| 1 | SIMPLE  | ap | ALL | NULL          | NULL     | NULL | NULL      | 3720 |         | 
+----+-------------+-------+--------+-------------------------------------------+----------------------+---------+--------------------------+------+---------------------------------+ 
+2

什麼解釋說? – exussum

+1

我不太擅長優化,但我會嘗試在附件表上粘貼一個複合索引(父,寬)。 – Strawberry

+0

所以這個查詢*慢*(和什麼是你的慢)或只是*長*? – fvu

回答

1

假設所有news記錄有sources,嘗試添加一個索引新聞上moderatedeletedate(按順序),然​​後嘗試以下查詢:

SELECT 
    n.id, 
    n.title, 
    n.text, 
    n.date, 
    IFNULL(ap.name, a.name) AS name, 
    IFNULL(ap.path, a.path) AS path, 
    IFNULL(ap.extension, a.extension) AS extension, 
    IFNULL(ap.width, a.width) AS width, 
    IFNULL(ap.height, a.height) AS height, 
    IFNULL(ap.server, a.server) AS server, 
    s.id AS source_id, 
    s.name AS source_name 
FROM (select * 
     from news 
     WHERE moderate = 1 AND delete = 0 
     ORDER BY date DESC 
     LIMIT 25) n 
LEFT JOIN news_attachments na ON n.id = na.news_id AND na.cover = 1 
LEFT JOIN attachments a ON na.attachments_id = a.id 
LEFT JOIN attachments ap ON a.id = ap.parent AND ap.width = 136 
JOIN sources s ON n.sources_id = s.id 
GROUP BY n.id 
+1

我還在最後添加了ORDER BY n.date DESC,因爲它顯示結果頭部高跟鞋 – user2058653

1

確保附件表有一個鍵父母(或可能更好的一個關鍵涵蓋煩惱父母和寬度)。懷疑這是主要問題。

我懷疑新聞表中的中等和刪除列將不會縮小到足以使索引對他們有用。

我還假設有更多的源記錄比新聞記錄,因此MySQL選擇採取消息來源,並加入新聞,而不是其他的方式。

+0

不,現在約4個來源,並且將是最大20-30。但是謝謝你的回答,這非常有用。 – user2058653

+0

哎呀,對不起,它錯了。意味着將有更多的新聞報道而不是消息來源,因此爲什麼它已經採取了消息來源並將新聞加入了這一消息。 – Kickstart