Я вижу 2 проблемы с оператором UPDATE
.
Нет индекса для полей End
. Составные индексы (annot
), которые вы используете, будут использоваться только для полей start
в этом запросе. Вы должны добавить их в соответствии с предложением Эмре:
ALTER TABLE `table_1` ADD INDEX ( `end` ) ;
ALTER TABLE `reference` ADD INDEX ( `txEnd` ) ;
Во-вторых, JOIN
может (и, вероятно, делает) найти много строк таблицы reference
, которые связаны со строкой table_1
. Таким образом, некоторые (или все) строки table_1
, которые обновляются, обновляются много раз. Проверьте результат этого запроса, чтобы увидеть, совпадает ли он с вашим обновленным количеством строк (17311434
):
SELECT COUNT(*)
FROM table_1
WHERE EXISTS
( SELECT *
FROM reference
WHERE table_1.start >= reference.txStart
AND table_1.`end` <= reference.txEnd
)
Могут быть другие способы написания этого запроса, но отсутствие PRIMARY KEY
в обеих таблицах усложняет его. Если вы определяете первичный ключ для table_1
, попробуйте это, заменив id
на первичный ключ.
Обновление : Нет, не пробуйте его на таблице с 34M строками. Проверьте план выполнения и попробуйте сначала с меньшими таблицами.
UPDATE table_1 AS t1
JOIN
( SELECT t2.id
, r.name
FROM table_1 AS t2
JOIN
( SELECT name, txStart, txEnd
FROM reference
GROUP BY txStart, txEnd
) AS r
ON t2.start >= r.txStart
AND t2.`end` <= r.txEnd
GROUP BY t2.id
) AS good
ON good.id = t1.id
SET t1.name = good.name;
План запроса можно проверить, запустив EXPLAIN для эквивалентного SELECT:
EXPLAIN
SELECT t1.id, t1.name, good.name
FROM table_1 AS t1
JOIN
( SELECT t2.id
, r.name
FROM table_1 AS t2
JOIN
( SELECT name, txStart, txEnd
FROM reference
GROUP BY txStart, txEnd
) AS r
ON t2.start >= r.txStart
AND t2.`end` <= r.txEnd
GROUP BY t2.id
) AS good
ON good.id = t1.id ;