MySQL:为什么这个过程比执行查询慢?

MySQL:为什么这个过程比执行查询慢?,mysql,sql,procedure,Mysql,Sql,Procedure,因此,我有一个superduper查询,它根据与$id变量中提供的原始文章相同的标记数查找相关文章。我不知道实际的查询是否重要,但这里是Justin Case 现在,我从来没有在实时项目中实际使用过过程,但我读过它们应该更快,部分原因是MySQL引擎不需要每次都解释代码。但当我将相同的代码放入一个过程并调用该过程时,执行时间平均要长450倍 为什么??是因为它返回了多行吗?程序真的很糟糕吗?是因为我必须在我的过程中使用输入变量吗?450是一堆 SELECT a.id, a.image, a.ti

因此,我有一个superduper查询,它根据与$id变量中提供的原始文章相同的标记数查找相关文章。我不知道实际的查询是否重要,但这里是Justin Case

现在,我从来没有在实时项目中实际使用过过程,但我读过它们应该更快,部分原因是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 ;

对您的延迟不是积极的,但在子选择中,其本身可能代价高昂。你有没有想过加入现在你的子选择?此外,由于articles表是查询的基础,并且a.id=rel.article\u id,因此如果通过索引提供,则a.id上的分组方式可能会更好

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

欢迎来到MySQL的真实世界! 有时很难说为什么一个查询比另一个查询执行的时间长。但在你的情况下,答案是:

MySQL不使用缓存,因为已从存储中调用查询 程序


我不知道你从哪里听说他们应该更快你用什么单位来测量450?450头骆驼?。我也不知道贾斯汀·凯斯是谁。调用存储过程的上下文是什么?看起来您可能没有正确使用它们。查询缓存是基于整个查询进行的,其中包括PHP变量提供的值。因此,随着变量的更改,查询缓存将无法重用。查询缓存也区分大小写。@AarolamaBluenk乘法因子不需要单位。如果将一个值与一个数字相乘,则得到与原始值相同的单位。贾斯汀·凯斯是一个超级英雄,只有在需要的时候才会出现——以防万一。上下文就是调用get_related_articles 17232。此调用的运行时间非常接近1秒,而执行实际查询的时间大约为2毫秒。@3Nex$id如何适合您的查询?你真的对你的查询进行了基准测试吗?@AarolamaBluenk忘了说这是PHP代码中的一行,所以MySQL会得到一个实际的整数。这个答案如何解释OP的存储过程慢的问题?@AarolamaBluenk,你是对的,但有时,对索引进行更好优化的查询的交替编写可以更好地执行,而不考虑其他情况。有时候,这只是一个采样的问题。我认为这里最大的问题是OP只需要10条记录,但却在连接上获取完整的结果集。这个查询的执行时间与我的查询的执行时间几乎相同,因此没有任何改进@AarolamaBluenk的评论,我不知道应该更改什么以避免不必要的结果集?不需要派生表/内联视图连接…-这可以作为内部联接条件来完成。但是,使用联接有可能将多个子记录与父记录相乘。