MySQL存储过程执行慢
1.现象:
1.执行MySQL存储过程在测试环境只要0.1s左右,到了生产环境qu却要5s左右,偏差很大。
2.非常简单的存储过程函数,处理的数据只有8条。
3.把存储过程里的查询单独拿出来查询速度很快,但是放在存储过程函数中就很慢。
2.原因:
数据库表中的字段是utf-8,而数据库字符集后来改成了utf8mb4。
存储过程中定义参数时,没有指定字符集,会默认读取创建存储过程时的全局变量character_set_server,就变成了utf8mb4编码。
utf8的,是不兼容utfbmb4的,字符集不同从而导致索引失效,进行导致执行变慢。
3.解决方案:
将索引的字符集改成utfbmb4。
4.问题的存储函数
CREATE DEFINER=`root`@`%` FUNCTION `getAVGResponseTime`(_sessionId varchar(32)) RETURNS int(11)
COMMENT ‘获取单次会话平均响应时间(s)‘
BEGIN
-- 完成循环
DECLARE v_finished INTEGER DEFAULT 0;
-- 响应次数
DECLARE cnt int DEFAULT 0;
-- 访客发送时间
DECLARE visitorSendTime int DEFAULT 0;
-- 聊天来源 1访客 2客服
DECLARE _fromType int ;
-- 会话类型 1机器人会话 2人工会话
DECLARE sessionType int ;
-- 发送时间
DECLARE _sendTime int ;
-- 客服接起时间
DECLARE _pickUpTime int;
-- 会话创建方式
DECLARE _createType int;
-- 总反应时间
DECLARE totalResponseTime DOUBLE DEFAULT 0.0;
-- 聊天游标
DECLARE sessionCursor CURSOR FOR (
SELECT TIME_TO_SEC(sendTime) sendTime,fromType
FROM chat_log
where sessionId =_sessionId
ORDER BY sendTime
);
-- 游标结束
DECLARE CONTINUE HANDLER
FOR NOT FOUND SET v_finished = 1;
-- 客服接起时间,创建类型,会话类型
SELECT TIME_TO_SEC(pickUpTime) ,createType,type INTO _pickUpTime,_createType,sessionType
FROM `session`
WHERE sessionId = _sessionId;
-- 机器人会话返回-1
IF sessionType = 1 THEN
return -1;
END IF;
-- 首次响应
SET visitorSendTime =_pickUpTime;
-- 开启游标
OPEN sessionCursor;
-- 遍历游标
loop1 : LOOP
-- 获取单条
FETCH sessionCursor INTO _sendTime,_fromType;
-- 游标结束退出循环
IF v_finished = 1 THEN
LEAVE loop1;
END IF;
IF _sendTime >_pickUpTime
THEN
-- 获取访客第一次发送时间
IF _fromType = 1 AND visitorSendTime = 0
THEN
SET visitorSendTime =_sendTime;
END IF;
-- 获取客服第一次响应时间
IF _fromType = 2 AND visitorSendTime>0
THEN
-- 总计响应时间
SET totalResponseTime =totalResponseTime + _sendTime -visitorSendTime;
-- 重置访客最后一次发送时间
SET visitorSendTime =0;
-- 响应次数+1
SET cnt =cnt +1;
END IF;
END IF;
END LOOP loop1;
-- 关闭游标
CLOSE sessionCursor;
-- 如果是客服创建减去首次响应时间
IF _createType = 3
THEN
SET cnt =cnt -1;
END IF;
-- 没有响应
IF cnt <= 0 THEN
RETURN -1;
END IF;
RETURN totalResponseTime/cnt;
END