2013-12-15 44 views
2

,所以我有這個疑問首先查詢採取更多然後在5秒鐘

SELECT a.`title`,a.`id`,a.`numvol`,a.`numepi`,a.`release_date`, 
    (SELECT COUNT(id) FROM `Release` r WHERE r.`article_id`=a.`id`) AS `num_rows`, 
    (SELECT COUNT(id) FROM `Article_views` av WHERE av.`article_id`=a.`id`) AS `num_rows2` 
FROM `Article` a WHERE a.`type` = 'ani' ORDER BY a.`title` ASC 

第一負載需要5秒,如果我做了刷新將需要大約0.001秒,是有辦法制服加載時間?

id select_type  table type possible_keys key  key_len  ref  rows Extra 
1 PRIMARY    a ALL  NULL   NULL NULL  NULL 567  Using where; Using filesort 
3 DEPENDENT SUBQUERY av ALL  NULL   NULL NULL  NULL 5301 Using where 
2 DEPENDENT SUBQUERY r ALL  NULL   NULL NULL  NULL 11717 Using where 

我試圖做它加入,但它並沒有在所有的工作,所以我放棄了這種方式...

解決方案

使用barmar查詢。更好的方式:)(和索引 - , - ')

id select_type  table   type  possible_keys key   key_len  ref  rows Extra 
1 PRIMARY   <derived2>  ALL  NULL   NULL  NULL  NULL 536  Using temporary; Using filesort 
1 PRIMARY   a    eq_ref PRIMARY   PRIMARY  4   r.art.. 1  Using where 
1 PRIMARY   <derived3>  ALL  NULL   NULL  NULL  NULL 574  Using where; Using join buffer 
3 DERIVED   Article_views index NULL   article_id 4   NULL 5301 Using index 
2 DERIVED   Release  index NULL   article_id 4   NULL 11717 Using index 

您的時間謝謝你們和解決方案:)我想我需要重做這老項目AHAH :)

+2

溫暖MySQL的緩存 –

+0

暖????這樣的小桌子真的需要那麼多時間嗎? – cloud1250000

+1

您的MyISAM或Innodb類型的表?我問,因爲它很重要 – mvp

回答

4

試試這個查詢,而不是:

SELECT a.`title`,a.`id`,a.`numvol`,a.`numepi`,a.`release_date`, `num_rows`, `num_rows2` 
FROM `Article` a 
JOIN (SELECT article_id, COUNT(*) AS num_rows 
     FROM Release 
     GROUP BY article_id) r 
ON r.article_id = a.id 
JOIN (SELECT article_id, COUNT(*) AS num_rows2 
     FROM Article_views 
     GROUP BY article_id) av 
ON av.article_id = a.id 
WHERE a.`type` = 'ani' 
ORDER BY a.`title` ASC 

根據我的經驗,連接比相關子查詢更快。

對於性能,請確保您有Release.article_idArticle_views.article_id指標。

+0

哇,這一個偉大的工作頭銜謝謝:)(0.0914秒)但索引是什麼?我添加了這些索引,它的執行方式與此相同:/它仍然更好:) – cloud1250000

+0

您正在使用數據庫構建應用程序,但不知道索引是什麼?我認爲你需要研究數據庫是如何工作的,我不打算在這裏教這個。 – Barmar

+0

我想我已經匆匆學習了一下,感謝你的時間;) – cloud1250000

2

我的很大一部分猜,第二次嘗試是受益於SQL QUERY CACHE。不知如果加入SQL_NO_CACHE,每次嘗試都需要5秒?

SELECT SQL_NO_CACHE a.`title`,a.`id`,a.`numvol`,a.`numepi`,a.`release_date`, 
.... 

指標

哎呀。你沒有相關的INDEX。你可以添加以下索引嗎?

ALTER TABLE Article ADD INDEX(type); 
ALTER TABLE Release ADD INDEX(article_id); 
ALTER TABLE Article_views ADD INDEX(article_id); 

更高效的查詢

,且查詢轉換爲JOIN。我想這比你的要快得多。假設每個ArticleReleaseArticle_views

SELECT a.`title`,a.`id`,a.`numvol`,a.`numepi`,a.`release_date`, 
    COUNT(r.id) AS `num_rows`, 
    COUNT(av.id) AS `num_rows2` 
FROM `Article` a JOIN Release r ON r.`article_id`=a.`id` 
    JOIN Article_views av ON av.`article_id`=a.`id` 
WHERE a.`type` = 'ani' 
GROUP BY a.title, a.id, a.numvol, a.numepi, a.release_date 
ORDER BY a.`title` ASC; 
+0

是的,你是對的,從另一方面增加SQL_NO_CACHE到查詢,它需要每次5秒......,你查詢不工作..它花了61.7727秒,並沒有返回NUM_ROWS和num_rows2 – cloud1250000

+0

@ cloud1250000對不起,可能是我犯了一些錯誤的正確計數。等一下。我會盡力解決。 –

+0

嗯,我剛剛看到,我需要添加相關索引..但它是做什麼? – cloud1250000

1

上查詢延遲顯著改善是由於內部的MySQL緩存功能。

第一次執行查詢後,結果集被高速緩存在RAM中,所以結果第二個查詢與前一個匹配,立即從RAM中取出,而無需HDD訪問。

關於MySQL內部緩存有不同的觀點,專家們經常建議在高負載生產環境中使用memecached,Redis或其他緩存層來禁用它。

但絕對應該嘗試優化緩存關閉時的查詢性能 - 5秒非常緩慢。

  1. 儘量不要使用子查詢,導致MySQL優化器不能執行它們。
  2. 將計數器的值(count()的結果)存儲在單獨的表中並正確更新它們。然後,只需在查詢中使用計數器值,而不必每次執行繁重的數據庫請求。
  3. 創建索引,例如,type字段。
  4. 使用EXPLAIN進一步優化