Я не вижу обработчик NOT FOUND
для вашего цикла выборки. Нет условия «выхода».
DECLARE done INT DEFAULT FALSE;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
Сразу после fetch
, проверить done
флаг и выйти из цикла, когда это верно.
IF done THEN
LEAVE load_loop;
END IF;
Без этого, я думаю, у вас есть классический бесконечный цикл.
В заявлении показано на SHOW FULL PROCESSLIST
выходе вставки в другой таблице. (Там нет _Temp
в конце имя_таблицы.)
Но почему на земле вам нужен цикл курсора для обработки строки за мучительной-строкой?
Если вам нужна таблица, загрузите ее, просто загрузите перевернутый стол и сделайте это.
Заменить все, что «объявить курсор», «открытый курсор», принеси цикл, обработчик выхода, отдельные вставки заявление нонсенс с одним утверждением, что делает то, что вам нужно сделать:
INSERT INTO Cached_Network_Observation_Temp (observation_id, `name`, id)
SELECT s.observation_id, s.name1 AS `name`, s.id1 AS id
FROM usanpn2.vw_Network_Observation s
WHERE s.id1 IS NOT NULL
Это будет быть более эффективным. И он не будет забивать двоичные журналы с разворотом ненужных инструкций INSERT. (Это также заставляет меня делать резервную копию на более крупную картинку и понимать, почему эта таблица даже нужна. Это также заставляет меня задаться вопросом, является ли представление vw_Network_Observation
и необходимо ли накладные расходы на материализацию производной таблицы. Предикат в этом внешнем запрос не попадает в определение представления. MySQL обрабатывает представления много иначе, чем другие РСУБД.)
EDIT
Если следующая часть процедуры, которая закомментирована проверяет ли id2
не нуль условно вставить id2
, name2
к столу _Temp, что может быть сделано таким же образом.
Или, несколько запросов могут быть объединены с оператором UNION ALL
.
INSERT INTO Cached_Network_Observation_Temp (observation_id, `name`, id)
SELECT s1.observation_id, s1.name1 AS `name`, s1.id1 AS id
FROM usanpn2.vw_Network_Observation s1
WHERE s1.id1 IS NOT NULL
UNION ALL
SELECT s2.observation_id, s2.name2 AS `name`, s2.id2 AS id
FROM usanpn2.vw_Network_Observation s2
WHERE s2.id2 IS NOT NULL
... и т.д.
Followup
Если нужно создать несколько строк из одной строки, а число строк не неоправданно большой, я бы соблазн проверить что-то подобное, обрабатывая id1
, id2
, id3
и id4
одним махом, используя CROSS JOIN
источника строки (s
) и искусственно созданный набор из четырех рядов.
Это будет генерировать четыре строки на строку из источника строк (s
), и мы можем использовать условные выражения для возврата id1
, id2
и т.д.
В качестве примера, что-то вроде этого:
SELECT s.observation_id
, CASE n.i
WHEN 1 THEN s.id1
WHEN 2 THEN s.id2
WHEN 3 THEN s.id3
WHEN 4 THEN s.id4
END AS `id`
, CASE n.i
WHEN 1 THEN s.name1
WHEN 2 THEN s.name2
WHEN 3 THEN s.name3
WHEN 4 THEN s.name4
END AS `name`
FROM usanpn2.vw_Network_Observation s
CROSS
JOIN (SELECT 1 AS i UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4) n
HAVING `id` IS NOT NULL
Мы используем предикат в предложении HAVING
вместо предложения WHERE
, потому что значение, генерируемое для столбца id
в наборе результатов, недоступно, когда к ним обращаются. Предикаты в предложении HAVING
применяются почти последним в плане выполнения, после, к которым обращаются строки, непосредственно перед возвратом строк. (Я думаю, что «FileSort» операция, чтобы удовлетворить ORDER BY
, и пункт LIMIT
применяется после HAVING
.)
Если количество строк, подлежащая обработке «очень большое», то мы можем получить лучшие строки обработки производительности в нескольких партиях разумного размера. Если мы делаем размер партии по два, обрабатывая две строки на INSERT, то эффективно половинки количество INSERT, которые нам нужно запустить. С 4 рядами за партию мы обрезаем это в половине. Как только мы достигнем пары десятков строк на каждую партию, у нас значительно сократил количество отдельных инструкций INSERT, которые нам нужно запустить.
Поскольку партии становятся все более крупными, наши показатели производительности становятся намного меньше. Пока партии не становятся громоздкими («слишком большими»), и мы начинаем бить на диск. Там есть «сладкое пятно» производительности между двумя крайностями (обработка одной строки за раз по сравнению с обработкой ВСЕ строк в одной партии).
Обработка RBAR (строка по мучительной строке). *ЗАЧЕМ*? Просто ** 'INSERT INTO Cached_Network_Observation_Temp SELECT observ_id, name1, id1 FROM usanpn2.vw_Network_Observation WHERE id1 NOT NULL' ** и делать с ним. Просто загрузите перелистающий стол. Нет необходимости запускать загрузку отдельных операторов SQL. (Вывод, показанный на выходе 'show processlist', является вставкой в * другую * таблицу, без' _Temp' в конце. – spencer7593
@ spencer7593 Это интересный подход!Я полагаю, я не думал об этом, потому что отдельные INSERTS должны запускаться на основе «нулевой» величины каждого из значений id. Но я могу сделать только одну вставку для каждого идентификатора в соответствии с вашим предложением. Я попробую и отправлю обратно. Тем не менее, мне все же было бы интересно узнать корень проблемы. – user470714
У вас бесконечный цикл. – Uueerdo