Заранее спасибо за попытку помочь мне!
Моя проблема заключается в следующем: у меня есть хранимая процедура fill_enrollment_id (). Эта процедура объявляет курсор, данные которого заполняют некоторые переменные, которые впоследствии используются для инструкции SELECT INTO для заполнения другой переменной (v_enrollmentid). Затем процедура проверяет, возвращает ли инструкция SELECT INTO исключение NOT FOUND. Если действительно возникает исключение NOT FOUND, то процедура выполняет ОБНОВЛЕНИЕ для столбца "enrollmentid" таблицы "mdl_edulevel2_log" со значением по умолчанию "0 - 0"; и затем обновляет переменную обработчика NOT FOUND, чтобы курсор мог выполнять итерации. В противном случае, если исключение не вызывается, процедура выполняет предложение UPDATE со значением, полученным с помощью инструкции SELECT INTO. Наконец, устанавливаются инструкции для закрытия курсора и выхода из l oop. Код процедуры выглядит следующим образом:
CREATE DEFINER=`mutual`@`%` PROCEDURE `fill_enrollment_id`()
BEGIN
DECLARE v_id BIGINT DEFAULT 0;
DECLARE v_userid BIGINT DEFAULT 0;
DECLARE v_courseid BIGINT DEFAULT 0;
DECLARE v_timecreated BIGINT DEFAULT 0;
DECLARE v_enrollmentid VARCHAR(255) DEFAULT null;
DECLARE exit_loop BOOLEAN;
DECLARE edulog_cursor CURSOR FOR SELECT id, userid, courseid, timecreated FROM mdl_edulevel2_log WHERE userid not in (0, 2, 3);
DECLARE CONTINUE HANDLER FOR NOT FOUND SET exit_loop = TRUE;
OPEN edulog_cursor;
edulog_loop: LOOP
FETCH edulog_cursor INTO v_id, v_userid, v_courseid, v_timecreated;
SELECT ifnull(enrollmentid, "0 - 0")
INTO v_enrollmentid
FROM mdl_enrollments
WHERE m_relateduserid = v_userid
AND m_courseid = v_courseid
AND ((v_timecreated >= m_timecreated) AND (v_timecreated <= dm_timecreated OR dm_timecreated = 0));
IF exit_loop THEN
UPDATE mdl_edulevel2_log
SET enrollmentid = "0 - 0"
WHERE id = v_id;
SET exit_loop = FALSE;
ELSE
UPDATE mdl_edulevel2_log
SET enrollmentid = v_enrollmentid
WHERE id = v_id;
END IF;
IF exit_loop THEN
CLOSE edulog_cursor;
LEAVE edulog_loop;
END IF;
END LOOP edulog_loop;
END
Мне кажется, что logi c в порядке, но процедура завершается с ошибкой Код ошибки 2013. Потерянное соединение с MySQL сервером во время запроса . Я действительно не знаю, почему это происходит. Моя интуиция говорит, что это связано с размером запроса курсора (143,115 строк) и тем фактом, что я запускаю это локально на моем ноутбуке (Intel® Core), i5 M250, 2,4 ГГц, 8 ГБ ОЗУ и 64 бита Windows 10 Pro). С другой стороны, интервал ожидания установлен на 600 в MySQL Workbench (см. Изображение ниже). Я не уверен, что увеличение этого значения решит проблему или усугубит ее.
![MySQL Workbench SQL Editor's Preferences](https://i.stack.imgur.com/03mV5.png)
Наконец, я поделюсь с вами определением Обе таблицы используются в процедуре (mdl_edulevel2_log и mdl_enrollments), поэтому вы можете видеть, что надлежащие индексы определены, поэтому процедура выполняется быстрее. Вот они:
CREATE TABLE `mdl_edulevel2_log` (
`id` bigint NOT NULL AUTO_INCREMENT,
`eventname` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
`component` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
`action` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
`target` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
`objecttable` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`objectid` bigint DEFAULT NULL,
`crud` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
`edulevel` tinyint(1) NOT NULL,
`contextid` bigint NOT NULL,
`contextlevel` bigint NOT NULL,
`contextinstanceid` bigint NOT NULL,
`userid` bigint NOT NULL,
`courseid` bigint DEFAULT NULL,
`relateduserid` bigint DEFAULT NULL,
`anonymous` tinyint(1) NOT NULL DEFAULT '0',
`other` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci,
`timecreated` bigint NOT NULL,
`origin` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`ip` varchar(45) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`realuserid` bigint DEFAULT NULL,
`enrollmentid` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `mdl_edulevel2log_tim_ix` (`timecreated`),
KEY `mdl_edulevel2log_couanotim_ix` (`courseid`,`anonymous`,`timecreated`),
KEY `mdl_edulevel2log_useconconcr_ix` (`userid`,`contextlevel`,`contextinstanceid`,`crud`,`edulevel`,`timecreated`),
KEY `mdl_edulevel2log_con_ix` (`contextid`),
KEY `idx_mdl_edulevel2_log_userid` (`userid`)
) ENGINE=InnoDB AUTO_INCREMENT=4727019 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='Standard log table';
CREATE TABLE `mdl_enrollments` (
`m_id` bigint NOT NULL,
`m_objectid` bigint DEFAULT NULL,
`m_userid` bigint NOT NULL,
`m_courseid` bigint DEFAULT NULL,
`m_relateduserid` bigint DEFAULT NULL,
`m_timecreated` bigint NOT NULL,
`m_ip` varchar(45) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`dm_id` bigint DEFAULT NULL,
`dm_objectid` bigint DEFAULT NULL,
`dm_userid` bigint DEFAULT NULL,
`dm_courseid` bigint DEFAULT NULL,
`dm_relateduserid` bigint DEFAULT NULL,
`dm_timecreated` bigint DEFAULT NULL,
`dm_ip` varchar(45) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`enrollmentid` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
PRIMARY KEY (`enrollmentid`),
KEY `idx_mdl_enrollments_m_relateduserid` (`m_relateduserid`),
KEY `idx_mdl_enrollments_m_courseid` (`m_courseid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='Standard log table';
Но, если честно, я не совсем уверен, что эти индексы используются. Я не знаю, чтобы сделать оператор EXPLAIN для вызова хранимой процедуры. Но когда я делал оператор EXPLAIN для запросов по отдельности, в них были результаты:
![Explain Statement for First Query in the Procedure](https://i.stack.imgur.com/1nZOF.png)
![Explain Statement for Second Query in the Procedure](https://i.stack.imgur.com/QhFd3.png)
![Explain Statement for Update Sentence in the Procedure](https://i.stack.imgur.com/KjVdb.png)
Итак, похоже, что индексы могут быть использованы, но, как я уже говорил, я не совсем уверен, что после вызова процедуры используются индексы.
Это все, что я могу сказать. Я надеюсь, что вы, ребята, можете дать мне несколько советов, подсказок или подсказок, чтобы решить эту проблему или решить ее другим способом. Не стесняйтесь спрашивать другую информацию, касающуюся данного вопроса, если, возможно, я уже не даю.
Привет из Венесуэлы и извините, если мой английский sh не достаточно ясен.