У меня есть хранимая процедура, когда я ее вызываю, время ожидания истекло.
Хранимая процедура выглядит следующим образом:
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
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