Я пытаюсь выполнить массовое обновление в таблице, содержащей 279 480 строк. Обновление должно запрашивать другую таблицу 1,113,770. Обновление выберет набор записей, а затем вычислит их сумму и применит результат к столбцу обновляемой таблицы.
Запрос отлично работает для отдельных строк, но при применении к полной таблице он терпит неудачу:
Error Code: 2013. Lost connection to MySQL server during query
Это делается внутри функции. Вот фактический запрос. Таблица счета-фактуры - это меньшая таблица:
LEGACYINVOICENO - это ПК для счета-фактуры. ПРОДАЖА - также индексированное поле, как и POSTDATE в счете-фактуре.
SELECT SUM(EXTENDEDPRICE)+SUM(TAX) FROM invoicedetail
WHERE LEGACYINVOICENO IN(
SELECT LEGACYINVOICENO FROM invoiceheader
WHERE SELLINGDEPARTMENT = _department
AND POSTDATE < _postdate
AND LOTJOB_ID = _ljID) into _balance_used;
Обновленная информация. Вот пример запроса, фактически работающего с использованием одного экземпляра:
SELECT SUM(EXTENDEDPRICE)+SUM(TAX) FROM invoicedetail
WHERE LEGACYINVOICENO IN(
SELECT LEGACYINVOICENO FROM invoiceheader
WHERE SELLINGDEPARTMENT = 2
AND POSTDATE < '2013-06-06'
AND LOTJOB_ID = '45497100FOXLAND1640')
План выполнения показывает, что вложенный цикл приводит к полному сканированию таблицы таблицы счета-фактуры. Это кажется вероятной причиной проблемы, но я не уверен, как мне нужно оптимизировать внутренний запрос.
В целях тестирования я упростил запрос:
SELECT SUM(EXTENDEDPRICE)+SUM(TAX) FROM invoicedetail
WHERE LEGACYINVOICENO IN(
SELECT LEGACYINVOICENO FROM invoiceheader
WHERE LOTJOB_ID = '45497100FOXLAND1640')
LEGACYINVOCENO - это PK, а LOTJOB_ID индексируется, но предложение WHERE все равно приводит к полному сканированию таблицы.
Не используйте IN ( SELECT... )
, переключитесь на JOIN... ON
. Вероятно, это предотвратит сканирование таблицы.
Покажите нам SHOW CREATE TABLE
чтобы мы знали, с чем вы работаете.
Для больших UPDATEs
, купите его.