2012-01-24 42 views
1

好的,所以我很抱歉,如果這個問題太基本了,但我通常只處理編程問題,而不是DBA問題。基本上,我試圖加快這個Django應用程序(注意:我沒有設計這個...只是堅持保持它),最大的瓶頸似乎是管理員正在生成的這些查詢。我們有一個內容類4-5其他子類繼承,隨時隨地主列表中會產生這樣的查詢管理員拉昇:SQL查詢優化

SELECT `content_content`.`id`, 
     `content_content`.`issue_id`, 
     `content_content`.`slug`, 
     `content_content`.`section_id`, 
     `content_content`.`priority`, 
     `content_content`.`group_id`, 
     `content_content`.`rotatable`, 
     `content_content`.`pub_status`, 
     `content_content`.`created_on`, 
     `content_content`.`modified_on`, 
     `content_content`.`old_pk`, 
     `content_content`.`content_type_id`, 
     `content_image`.`content_ptr_id`, 
     `content_image`.`caption`, 
     `content_image`.`kicker`, 
     `content_image`.`pic`, 
     `content_image`.`crop_x`, 
     `content_image`.`crop_y`, 
     `content_image`.`crop_side`, 
     `content_issue`.`id`, 
     `content_issue`.`special_issue_name`, 
     `content_issue`.`web_publish_date`, 
     `content_issue`.`issue_date`, 
     `content_issue`.`fm_name`, 
     `content_issue`.`arts_name`, 
     `content_issue`.`comments`, 
     `content_section`.`id`, 
     `content_section`.`name`, 
     `content_section`.`audiodizer_id` 
    FROM `content_image` 
INNER 
    JOIN `content_content` 
    ON `content_image`.`content_ptr_id` = `content_content`.`id` 
INNER 
    JOIN `content_issue` 
    ON `content_content`.`issue_id` = `content_issue`.`id` 
INNER 
    JOIN `content_section` 
    ON `content_content`.`section_id` = `content_section`.`id` 
WHERE NOT (`content_content`.`pub_status` = -1) 
ORDER BY `content_issue`.`issue_date` DESC LIMIT 30 

我跑這一個解釋並得到了以下:現在

+----+-------------+-----------------+--------+-------------------------------------------------------------------------------------------------+---------+---------+--------------------------------------+-------+---------------------------------+ 
| id | select_type | table   | type | possible_keys                     | key  | key_len | ref         | rows | Extra       | 
+----+-------------+-----------------+--------+-------------------------------------------------------------------------------------------------+---------+---------+--------------------------------------+-------+---------------------------------+ 
| 1 | SIMPLE  | content_image | ALL | PRIMARY                       | NULL | NULL | NULL         | 40499 | Using temporary; Using filesort | 
| 1 | SIMPLE  | content_content | eq_ref | PRIMARY,issue_id,content_content_issue_id,content_content_section_id,content_content_pub_status | PRIMARY | 4  | content_image.content_ptr_id   |  1 | Using where      | 
| 1 | SIMPLE  | content_section | eq_ref | PRIMARY                       | PRIMARY | 4  | content_content.section_id   |  1 |         | 
| 1 | SIMPLE  | content_issue | eq_ref | PRIMARY                       | PRIMARY | 4  | content_content.issue_id    |  1 |         | 
+----+-------------+-----------------+--------+-------------------------------------------------------------------------------------------------+---------+---------+--------------------------------------+-------+---------------------------------+ 

,從我讀過,我需要以某種方式弄清楚如何使查詢content_image不可怕;然而,我正在從哪裏開始畫空白。 SQL並不完全是我最強大的領域,所以任何幫助將不勝感激。

+0

您從'content_image'表中選擇** everything **(因爲您沒有任何可以過濾掉某些行的WHERE) - 所以您有一個表fullscan。你還期望看到什麼? – zerkms

回答

2

目前,通過執行計劃判斷,MySQL是開始content_image,檢索所有行,並且僅在其後使用主鍵上的其他表:content_image具有外鍵content_content,和content_content具有外鍵content_issuecontent_section。另外,只有在所有連接完成之後,纔可以使用ORDER BY content_issue.issue_date DESC LIMIT 30,因爲它無法分辨哪些連接可能會失敗,因此,在獲得前三十個連接之前真的需要多少個content_issue的記錄輸出行。

所以,我會嘗試以下方法:

  • 變化JOIN content_issueJOIN (SELECT * FROM content_issue ORDER BY issue_date DESC LIMIT 30) content_issue。這將允許MySQL,如果它以content_issue開頭,並且運行到其他表,則可以獲取content_issue的一個非常小的子集。
    • 注意:正確地說,這改變了查詢的語義:這意味着最多隻有最後30個content_issue的記錄纔會被檢索到,因此如果其中一些問題沒有發佈帶有圖像的內容,那麼將檢索少於30條記錄。我沒有足夠的關於數據的信息來判斷這種語義變化是否會改變你得到的結果。
    • 另請注意:我不建議從查詢結尾刪除ORDER BY content_issue.issue_date DESC LIMIT 30。我想你想在兩個地方。
  • content_issue.issue_date上添加索引來優化上述子查詢。
  • content_image.content_ptr_id上添加索引,因此MySQL可以在不進行全表掃描的情況下從content_contentcontent_image工作。
+0

感謝您的幫助和解釋!我會給它一個鏡頭。 – ebensing