2013-03-07 27 views
0

所以我有這個superduper查詢找到「相關文章」基於他們有共同的原始文章(在$ id變量中提供)的標籤數量。我不知道實際的查詢是否重要,但這裏是Justin Case。MySQL:程序如何比執行查詢慢?

現在,我從來沒有在實際項目中實際使用過程,但我讀過它們應該更快,部分原因是MySQL引擎不需要每次都解釋代碼。但是當我把這個相同的代碼放在一個過程中並調用過程時,執行時間平均延長了大約450倍。

爲什麼?是因爲它返回多行嗎?程序是否對此感到厭煩?是否因爲我必須在我的程序中使用輸入變量? 450是一堆!

SELECT a.id, a.image, a.title, a.excerpt, a.permalink, COUNT(rel.category_id) AS n 
    FROM articles AS a 
    JOIN category_relations AS rel ON rel.article_id = a.id 
    JOIN categories AS c ON rel.category_id = c.id 
WHERE rel.category_id IN (SELECT category_id 
          FROM category_relations 
          WHERE article_id = {$id}) 
    AND a.id != {$id} 
    AND c.type = 1 
GROUP BY rel.article_id 
ORDER BY n DESC, publish_date DESC 
    LIMIT 10 

代碼用於創建過程:

DROP PROCEDURE IF EXISTS get_related_articles; 
DELIMITER // 
CREATE PROCEDURE get_related_articles(IN id INT) 
BEGIN 
    SELECT a.id, a.image, a.title, a.excerpt, a.permalink, COUNT(rel.category_id) AS n 
    FROM  articles AS a 
    JOIN category_relations AS rel ON rel.article_id = a.id 
    JOIN categories AS c ON rel.category_id = c.id 
    WHERE rel.category_id IN (SELECT category_id FROM category_relations WHERE article_id = id) 
    AND a.id != id 
    AND c.type = 1 
    GROUP BY rel.article_id 
    ORDER BY n DESC, publish_date DESC 
    LIMIT 10; 
END // 
DELIMITER ; 
+1

我不確定你在哪裏聽說他們應該更快(你用什麼單位測量450?450駱駝?)。我也不知道賈斯汀凱斯是誰。存儲過程被調用的上下文是什麼?看起來你可能沒有正確使用它們。 – Kermit 2013-03-07 03:15:18

+0

查詢緩存基於整個查詢進行 - 包括您的PHP變量提供的值。所以隨着變量的變化,查詢緩存不能被重用。查詢緩存也是區分大小寫的。 – 2013-03-07 03:15:58

+0

@AarolamaBluenk你不需要乘法因子單位。如果用一個數字乘以一個值,就會得到與原始值相同的單位。賈斯汀凱斯是一個超級英雄,只有在需要時才顯示出來(以防萬一)。上下文只是「CALL get_related_articles(17232)」。此調用運行時間非常接近1秒,而執行實際查詢運行大約2 ms。 – 3Nex 2013-03-07 03:26:31

回答

0

你的延遲並不積極,但在子查詢本身可以是昂貴的。你有沒有想過加入到現在的子選擇中?另外,由於articles表是查詢的基礎,而a.id = rel.article_id,所以如果通過索引可用,則「a.id」上的group by可能會更好。

SELECT 
     a.id, 
     a.image, 
     a.title, 
     a.excerpt, 
     a.permalink 
    FROM 
     articles AS a 
     JOIN category_relations AS rel 
      ON a.id = rel.article_id 
      JOIN categories AS c 
       ON rel.category_id = c.id 
       AND c.type = 1 
      JOIN (SELECT category_id 
        FROM admin_category_relations 
        WHERE article_id = {$id}) RelByArticle 
       on rel.category_id = RelByArticle.category_id 
    WHERE 
     a.id != {$id} 
    GROUP BY 
     a.id 
    ORDER BY 
     n DESC, 
     publish_date DESC 
    LIMIT 10 
+0

這個答案是如何解釋OP的存儲過程緩慢的問題? – Kermit 2013-03-07 03:29:04

+0

@AarolamaBluenk,你是對的,但有時候,爲索引更好地優化查詢的替代寫法可以更好地執行,無論其他事情如何。有時,它只是一個抽樣問題。 – DRapp 2013-03-07 03:32:37

+0

我認爲這裏最大的問題是OP只需要10條記錄,但是卻在連接上獲取完整的結果集。 – Kermit 2013-03-07 03:36:13

0

歡迎來到MySQL的真實世界! 有時很難說爲什麼一個查詢執行的時間比另一個長。但是,在你的情況,答案可以找到here

MySQL不使用查詢緩存從存儲 程序已經調用。