MySQL: How come the procedure is slower than executing the query?

ぐ巨炮叔叔 提交于 2019-12-25 06:57:25

问题


So i have this superduper query that finds "related articles" based on the number of tags they have in common with the original article (provided in the $id variable). I don't know if the actual query is important, but here it is Justin Case.

Now, I've never actually used procedures in a live project, but I've read they should be faster, partially because the MySQL engine doesn't need to interpret the code each time. But when i had put this same code in a procedure and called the procedure, the execution was on average about 450 times longer.

Why? Is it because it's returning multiple rows? Do procedures stink at that? Is it because i have to use an input variable in my procedure? 450 is a bunch!

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

Code used to create the procedure:

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:


Welcome to the real world of MySQL! Sometimes it's very hard to say why one query executes longer that another. But in your case the answer can be find here:

MySQL doesn't use cache for queries have been called from stored procedures.




回答2:


Not positive on your delay, but IN SUBSELECTS can themselves be costly. Have you thought of doing a join to what is now your sub-select? Also, since the articles table is basis of query, and a.id = rel.article_id, your group by on the "a.id" might be better if available via index.

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


来源:https://stackoverflow.com/questions/15262397/mysql-how-come-the-procedure-is-slower-than-executing-the-query

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!