调用它时,我有一个存储过程,它将超时。
存储过程如下:
CREATE DEFINER=`root`@`localhost` PROCEDURE `DeleteAttachmentsByIDs`(IN p_ids nvarchar(1024), IN p_modifiedBy varchar(100), IN p_modifiedDate datetime)
BEGIN
CALL splitter(p_ids, ',');
update attachments set
`IsDeleted` = 1
, `ModifiedBy` = p_modifiedBy
, `ModifiedDate` = p_modifiedDate
where
id in (select * from splitResults);
END
我用以下代码称呼它:
CALL`DeleteAttachmentsByIDs`('12479,12480,12481', 'admin', '2019-04-03 09:38:50.072608')
我试图将存储过程更改为
CREATE DEFINER=`root`@`localhost` PROCEDURE `DeleteAttachmentsByIDs`(IN p_ids nvarchar(1024), IN p_modifiedBy varchar(100), IN p_modifiedDate datetime)
BEGIN
CALL splitter(p_ids, ',');
select * from splitResults;
END
它将迅速返回结果,如下所示
'12479'
'12480'
'12481'
当我尝试如下手动运行时,它也可以快速运行
update attachments set
`IsDeleted` = 1
, `ModifiedBy` = 'admin'
, `ModifiedDate` = '2019-04-03 09:38:50.072608'
where
id in (12479,12480,12481);
所以我不明白在此存储过程中发生了什么事情,这使得它运行得如此缓慢,我该如何改善呢?
CREATE DEFINER=`root`@`localhost` PROCEDURE `DeleteAttachmentsByIDs`(IN p_ids nvarchar(1024), IN p_modifiedBy varchar(100), IN p_modifiedDate datetime)
BEGIN
CALL splitter(p_ids, ',');
update attachments set
`IsDeleted` = 1
, `ModifiedBy` = p_modifiedBy
, `ModifiedDate` = p_modifiedDate
where
id in (select * from splitResults);
END
这里是创建splitResults的splitter函数
DELIMITER $$
CREATE DEFINER=`root`@`localhost` PROCEDURE `splitter`(x varchar(255), delim varchar(12))
BEGIN
SET @Valcount = substrCount(x,delim)+1;
SET @v1=0;
drop table if exists splitResults;
create temporary
table splitResults (split_value varchar(255));
WHILE (@v1 < @Valcount) DO
set @val = stringSplit(x,delim,@v1+1);
INSERT INTO splitResults (split_value) VALUES (@val);
SET @v1 = @v1 + 1;
END WHILE;
END
我向存储过程添加了说明
CREATE DEFINER=`root`@`localhost` PROCEDURE `DeleteAttachmentsByIDs`(IN p_ids nvarchar(1024), IN p_modifiedBy varchar(100), IN p_modifiedDate datetime)
BEGIN
CALL splitter(p_ids, ',');
explain update attachments set
`IsDeleted` = 1
, `ModifiedBy` = p_modifiedBy
, `ModifiedDate` = p_modifiedDate
where
id in (select * from splitResults);
END
这是执行计划的结果
id, select_type, table, partitions, type, possible_keys, key, key_len, ref, rows, filtered, Extra
1, UPDATE, attachments, , index, , PRIMARY, 4, , 12301, 100.00, Using where
2, DEPENDENT SUBQUERY, splitResults, , ALL, , , , , 3, 33.33, Using where