Mysql语句单独执行很快,但放存储过程里执行很慢

gcmud 2017-05-22 11:52:41
查阅慢日志发现一个存储过程执行很慢,但里面的语句都很简单,相关表对应的主键和索引也都有,而且把语句拿出来单独执行都很快。请教大家知道是什么问题不?

存储过程为:
CREATE DEFINER = `wegameroot2016`@`%` PROCEDURE `csp_DelGroupBroadComment`(p_groupID varchar(30), p_langType varchar(2), p_broadID bigint, p_commentID int, p_delTime datetime, p_delUserID int)
BEGIN
declare p_sendUserID int;
declare p_state tinyint;

declare RETURN_VALUE int;
set RETURN_VALUE=0;

select State into p_state from cht_groupbroadinfo where GroupID=p_groupID and LangType=p_langType and BroadID=p_broadID;
if FOUND_ROWS()=0 then
set RETURN_VALUE=1;/*?????*/
elseif p_state=2 then
set RETURN_VALUE=2;/*??????*/
else
select SendUserID, State into p_sendUserID, p_state from cht_groupbroadcommentinfo where GroupID=p_groupID and LangType=p_langType and BroadID=p_broadID and CommentID=p_commentID;
if FOUND_ROWS()=0 then
set RETURN_VALUE=3;/*?????*/
elseif p_state=2 then
set RETURN_VALUE=4;/*??????*/
elseif p_delUserID>0 and p_sendUserID<>p_delUserID then
set RETURN_VALUE=5;/*??????????*/
else
update cht_groupbroadcommentinfo set State=2, StateChangeTime=p_delTime where GroupID=p_groupID and LangType=p_langType and BroadID=p_broadID and CommentID=p_commentID;
end if;
end if;

select RETURN_VALUE;
END;

执行调用为:
call csp_DelGroupBroadComment('PetGame', 'CN', 117685, 12, '2017-05-22 10:23:17.873', 0);
执行很慢,要1分钟,RETURN_VALUE结果是4,就慢在里面的“select SendUserID, State from cht_groupbroadcommentinfo”这条语句上。

单独拿出来:很快很快
set @groupID='PetGame';
set @langType='CN';
set @broadID=117685;
set @commentID=12;
select SendUserID, State from cht_groupbroadcommentinfo where GroupID=@groupID and LangType=@langType and BroadID=@broadID and CommentID=@commentID;

表cht_groupbroadcommentinfo 有主键和索引如下:
PRIMARY KEY (`GroupID`, `LangType`, `BroadID`, `CommentID`),
INDEX `idx_senduser` (`SendUserID`, `GroupID`, `LangType`, `SendTime`) USING BTREE ,
INDEX `idx_state` (`GroupID`, `LangType`, `BroadID`, `State`, `CommentID`) USING BTREE

大家帮忙看看有什么头绪吗?
...全文
2095 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
Lyn_0629 2017-07-10
  • 打赏
  • 举报
回复
您好,我也遇到类似的问题,请教下是什么原因导致SQL慢?
Lyn_0629 2017-07-07
  • 打赏
  • 举报
回复
您好,我也遇到这个问题,能否说下原理,是什么导致这种情况发生?非常感谢
gcmud 2017-05-22
  • 打赏
  • 举报
回复
表cht_groupbroadcommentinfo是InnoDB,DataLength为443392KB,Rows为2618673条。
gcmud 2017-05-22
  • 打赏
  • 举报
回复
问题已经解决。多谢zjcxc的回复,为我提供了思路。其实这个问题我以前解决过,但时间久了忘记了。 修改后的存储过程如下(每次定义一个PREPARE然后DEALLOCATE不知道是否合适,没用过): CREATE PROCEDURE `csp_DelGroupBroadComment`(p_groupID varchar(30), p_langType varchar(2), p_broadID bigint, p_commentID int, p_delTime datetime, p_delUserID int) BEGIN declare RETURN_VALUE int; set RETURN_VALUE=0; set @groupID=p_groupID; set @langType=p_langType; set @broadID=p_broadID; set @commentID=p_commentID; set @delTime=p_delTime; set @state=0; set @stmt='select State into @state from cht_groupbroadinfo where GroupID=? and LangType=? and BroadID=?;'; PREPARE stmt1 from @stmt; EXECUTE stmt1 USING @groupID, @langType, @broadID; DEALLOCATE PREPARE stmt1; if FOUND_ROWS()=0 then set RETURN_VALUE=1;/*?????*/ elseif @state=2 then set RETURN_VALUE=2;/*??????*/ else set @sendUserID=0; set @state=0; set @stmt='select SendUserID, State into @sendUserID, @state from cht_groupbroadcommentinfo where GroupID=? and LangType=? and BroadID=? and CommentID=?;'; PREPARE stmt2 from @stmt; EXECUTE stmt2 USING @groupID, @langType, @broadID, @commentID; DEALLOCATE PREPARE stmt2; if FOUND_ROWS()=0 then set RETURN_VALUE=3;/*?????*/ elseif @state=2 then set RETURN_VALUE=4;/*??????*/ elseif p_delUserID>0 and @sendUserID<>p_delUserID then set RETURN_VALUE=5;/*??????????*/ else set @stmt='update cht_groupbroadcommentinfo set State=2, StateChangeTime=? where GroupID=? and LangType=? and BroadID=? and CommentID=?;'; PREPARE stmt3 from @stmt; EXECUTE stmt3 USING @delTime, @groupID, @langType, @broadID, @commentID; DEALLOCATE PREPARE stmt3; end if; end if; select RETURN_VALUE; END;
gcmud 2017-05-22
  • 打赏
  • 举报
回复
引用 6 楼 zjcxc 的回复:
@groupID=p_groupID的方式代替各个参数 ------------------ 这里面是不是错了? p_GroupID 不是你的参数么? 这样弄不是查所有数据的意思 了?
没错阿,就是用@groupID代替p_groupID。但mysql估计和sql server不一样,并没有效果。
zjcxc 2017-05-22
  • 打赏
  • 举报
回复
@groupID=p_groupID的方式代替各个参数 ------------------ 这里面是不是错了? p_GroupID 不是你的参数么? 这样弄不是查所有数据的意思 了?
gcmud 2017-05-22
  • 打赏
  • 举报
回复
引用 3 楼 zjcxc 的回复:
新建一个同样内容的存储过程,如果执行快,那说明之前的存储过程执行计划过期了,删除重建 如果仍然有问题,试试把存储过程里面的 参数 改成变量,然后调用,如果性能好了,说明在参数的处理和变量的处理上,执行计划不同,可以考虑在内部用变量代替参数(sql server 中曾经遇到过这种问题)
重建存储过程一样的。 在里面用@groupID=p_groupID的方式代替各个参数,然后使用@groupID的参数来执行也很慢。 在里面用@groupID=‘PetGame'的方式用值直接代替各个参数,然后使用@groupID的参数来执行就秒完成了。 但这样我应该怎么改,莫非不能使用存储过程了。。。。
gcmud 2017-05-22
  • 打赏
  • 举报
回复
引用 3 楼 zjcxc 的回复:
新建一个同样内容的存储过程,如果执行快,那说明之前的存储过程执行计划过期了,删除重建 如果仍然有问题,试试把存储过程里面的 参数 改成变量,然后调用,如果性能好了,说明在参数的处理和变量的处理上,执行计划不同,可以考虑在内部用变量代替参数(sql server 中曾经遇到过这种问题)
谢谢,我试试。
zjcxc 2017-05-22
  • 打赏
  • 举报
回复
新建一个同样内容的存储过程,如果执行快,那说明之前的存储过程执行计划过期了,删除重建 如果仍然有问题,试试把存储过程里面的 参数 改成变量,然后调用,如果性能好了,说明在参数的处理和变量的处理上,执行计划不同,可以考虑在内部用变量代替参数(sql server 中曾经遇到过这种问题)
gcmud 2017-05-22
  • 打赏
  • 举报
回复
不要沉啊,在线等。

56,677

社区成员

发帖
与我相关
我的任务
社区描述
MySQL相关内容讨论专区
社区管理员
  • MySQL
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧