存储过程在数据量大时无法正常执行怎么办?

lyhj0001 2018-11-15 01:42:06
最近接手一个公司外包维护,他们系统有一些数据处理使用的是Mysql的存储过程定时执行来实现的。最近这几天这个存储过程虽然每天都有执行,但全都失败了。

手动执行时有一些返回: 1364 - Field 'shop_id' doesn't have a default value。

问题是这个存在过程是通过把一个主表连接两个附表里的数据按过滤条件取出来,然后插入到一个新表里。

这个取的过程如果直接在命令行是正常的,大概数据是230W条左右。表里数据大概有2亿多点。

它执行报的这个错误这个取出来的shop_id不可能是没有值的,我单独执行存储过程的SELECT操作,然后按shop_id排序的都是有值的。

有人知道这是为什么吗?现在这个存在过程从前两天开始已经没法正常执行了。前些天数据大概在150W左右时还能正常执行。现在200W时就执行不下去了。

存储过程代码:

BEGIN
/*
** Step 1
** 名称:Temp
** 参数:无
*/
DECLARE
#a date DEFAULT DATE_SUB(CURDATE(),INTERVAL 1 DAY); # "2017-11-12"
a date DEFAULT "2018-11-12";
DECLARE staffds INT DEFAULT 18000 ; -- 默认当日在线时长超过5小时即为店员
DECLARE outshops INT DEFAULT 0 ; -- 默认当日在线时长少过60秒的即为店外流量
WHILE
a < CURDATE( ) DO
INSERT INTO shuibei_lbs.LBS_MessData ( TransactionDate, shop_id, ApMac, ClientMac, ClientDeviceBrand, EnterTime, Exittime, Inshop, DurationSecond ) SELECT
DATE( A.EnterTime ) AS TransactionDate,
# B.remarks,
B.shop_id,
upper( A.EnterSensorMac ) AS ApMac,
Upper( A.ClientMac ),
"" AS ClientDeviceBrand,
A.EnterTime,
A.ExitTime,
CASE
WHEN A.Rssi >= B.device_rssi

THEN
1 ELSE 0
END,
TIME_TO_SEC( TIMEDIFF( A.ExitTime, A.EnterTime ) ) AS DurationBySecond
FROM
shuibei_lbs.LBS_CustomerRegionEvent A,
shuibei_lbs.shop_device B
WHERE
DATE_FORMAT( A.EnterTime, "%Y-%m-%d" ) = a
AND upper( A.EnterSensorMac ) = B.device_mac
# AND A.Rssi >= B.device_limit_rssi
#and TIME_TO_SEC( TIMEDIFF( A.ExitTime, A.EnterTime ) ) > outshops
ORDER BY
EnterTime;

-- 更新设备品牌
UPDATE shuibei_lbs.LBS_MessData A,
shuibei_lbs.oui B
SET A.ClientDeviceBrand = LEFT ( B.CompanyName, 200 )
WHERE
upper( LEFT ( A.ClientMac, 8 ) ) = B.MAC
AND TransactionDate = a;

-- 筛选出职员清单
INSERT INTO shuibei_lbs.StaffList (ClientMac)
SELECT
distinct TempT.ClientMac
from (SELECT TransactionDate,shop_id,ClientMac, sum(DurationSecond) DS
FROM shuibei_lbs.LBS_MessData
where TransactionDate = a
group by TransactionDate, shop_id, ClientMac
order by TransactionDate, shop_id, ClientMac) TempT
WHERE TempT.DS >= staffds
and TempT.ClientMac not in (select distinct ClientMac from shuibei_lbs.StaffList);

SET a = DATE_ADD( a, INTERVAL 1 DAY );

END WHILE;

END
...全文
184 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复 1
看了下存储过程大概分三步,插入数据,更新数据,再插入数据; 建议手动执行三个SQL语句,查看哪条SQL报错,根据你描述的应该是第一条SQL; 你查一下select * from b where shop_is null; 看真的是否有空值 如果还有没建议你把插入的SELECT语句单独执行,不要用肉眼看,加个条件 where shop_id is null; 查看是否会真的产生空值。 如果都排除了,刚才看了下其他人1364经验,是这样说的: 修改SQL_MODE 但不建议,你是把不规范的值插入到了表中,才会报这个错误。 看SHOP_ID字段长度, 然后把SELECT 语句生成的SHOP_ID你再LENGTH一下,是不是有人手动输入错误,导致字度过长插入不进去。 建议还是从SHOP_id这列数据入手,查找不规范的数据。

56,677

社区成员

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

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