目录
情景
有一个项目价格体系表和一个项目订单表,项目价格表里面的价格更新,项目订单表里面的对应没有结算的订单价格更新 订单表更新后往来资金里面需要重新更新,现在项目订单数量太大,更新的时候太慢。
第一次处理
用触发器去处理 监听订单表,订单表被更新时触发器自动去更新往来资金表,但是触发器有一个坏处,我update我的订单表 是不行的,所以gg。
第二次处理
因为用到了上偏文章的FIND_IN_SET 所以我有个大胆的想法
BEGIN
DECLARE temp int(11);
SET temp = 0;
#项目销售
update income_pay_info ip
join (
select
delivery_order_number,
take_unit_id,
sale_unit_price,
check_weight
from
delivery_order
where
FIND_IN_SET(id, numbers)
) new on ip.source_order_number = new.delivery_order_number
set amount = new.check_weight * new.sale_unit_price
where
ip.unit_id = new.take_unit_id
and ip.source_type = 1
and ip. status = 0;
RETURN temp;
end
我把我修改到的订单号(numbers)传到我的函数里面 我把需要的数据查到再进行修改 这样刚开始还好但是数据量慢慢大了就很慢 我加索引也没有用 这是因为丿date关联表修改就慢 这会造成全表扫描。
最后一次机会 给点面子 别给脸不要脸啊
又叫我改 真的是 客户问为什么慢 公司老哥来了个 你们带宽不够 这波忽悠 我又马上开始改
一二再 再而三,给个机会让我下次不要再改了,我终于在茫茫人海中找到了她——“快速游标更新法”
但是我看这MySQL不能用啊
不行 我要看哈美女冷静一下
oracle中游标的使用
冷静一下终于好了 还是开始我们今天的重头戏吧——好戏开场了 管好你的嘴 小子
方法一:隐试游标(更新一次提交一次)
begin
for cr in (查询语句) loop --循环
update table_name set ... --更新语句
commit; --提交
end loop; --结束循环
end;
方法二:隐试游标(更新一千次提交一次)(推荐使用)
declare v_count numbers(10);
begin
for cr in (查询语句) loop --循环
update table_name set ... --更新语句
v_count := v_count + 1;
if v_count >= 1000 then
commit; --提交
v_count := 0;
end if;
end loop; --结束循环
end;
为什么使用一千提交一次呢(自己人的默契)
方法三:推荐使用(使用 BULK COLLECT 和FORALL)
为啥我那么喜欢三呢(其实因为我懒啊 要不是没有事情做 我才不在这里写博客)
你看 我就是这样的人
游标在MySQL中使用
直接上代码
BEGIN
DECLARE delivery_order_number VARCHAR(50);
DECLARE take_unit_id INT;
DECLARE sale_unit_price DECIMAL(8,2);
DECLARE check_weight DECIMAL(8,2);
-- 这个变量用于处理游标到最后一行的情况
DECLARE s INT DEFAULT 0;
-- 声明游标new (new是一个多行结果集)
DECLARE new CURSOR FOR
SELECT delivery_order_number, take_unit_id, sale_unit_price, check_weight
FROM delivery_order
WHERE FIND_IN_SET(id, numbers);
-- 设置一个终止标记,SQLSTATE '02000'是一个未找到条件
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET s = 1;
-- 打开游标
OPEN new;
-- 获取游标当前指针的记录,读取一行数据并传递给变量
FETCH new INTO delivery_order_number, take_unit_id, sale_unit_price, check_weight;
-- 开始循环,判断是否游标已经到了最后作为循环条件
WHILE s <> 1 DO
#供应商
UPDATE income_pay_info ip
SET ip.amount = check_weight * sale_unit_price
WHERE ip.source_order_number = delivery_order_number
AND ip.unit_id = take_unit_id
AND ip.source_type = 1
AND ip.`status` = 0;
-- 读取下一行的数据
FETCH NEXT FROM new INTO delivery_order_number, take_unit_id, sale_unit_price, check_weight;
END WHILE;
-- 关闭游标
CLOSE new;
END
看注解吧 还是很清楚的 我要去恰饭了,订单号还是通过numbers传进来的,谁的饭 好香啊,拜拜了您勒!