Обновление MySQL с подвыбором слишком медленное - PullRequest
1 голос
/ 02 июня 2011

Проблема с запросом на обновление, занимающим более 20 минут (я убиваю его после этого).

Сценарий:

Таблица 1 содержит несколько записей по 300 КБ.

Таблица 2 содержит тот же набор записей (скопированный), но с дополнительным полем, которое должно содержать идентификатор записи, которая соответствует количеству полей и имеет наибольшее значение другой (оценка).Чтобы уточнить, конечным результатом должна быть таблица два, содержащая записи по 300 КБ, каждая из которых имеет идентификатор другой записи с таким же набором базовых свойств, а также самый высокий балл в наборе записей с этими свойствами.

Приведенное ниже завершается через ~ 5 с, когда я копирую только записи 2K вместо полных записей 300k в таблицу 2.

UPDATE vtable2 v1 SET v1.buddy = (
    SELECT v2.id FROM vtable1 v2
    WHERE
    v2.group_id = v1.group_id AND
    // 6 more basic comparisons
    ORDER BY score DESC LIMIT 1
)

Мне нужно найти друзей для полных записей 300K.Все поля, связанные с объединением и сортировкой, имеют индексы.

Помощь очень ценится.

Ответы [ 3 ]

1 голос
/ 02 июня 2011

Подзапросы MySQL, как правило, немного медленнее.Я предпочитаю использовать соединения в таких случаях.Я не совсем понимаю ваш дизайн схемы - но вы можете попробовать что-то вроде этого -

UPDATE vtable2 v1
[INNER] JOIN vtable1 v2 
ON v2.group_id = v1.group_id
AND //OTHER JOIN CONDITIONS IF ANY
WHERE
//any other conditions
SET
v1.buddy = v2.id

PS - Конечно, вы должны убедиться, что у вас есть правильные индексы для ваших столбцов.Если вам нужна помощь в этом, вы можете опубликовать весь запрос с планом объяснения.

0 голосов
/ 02 июня 2011

Вы можете использовать исключающее соединение , чтобы найти строку в vtable1 так, чтобы не было найдено другой строки в vtable1 с более высоким счетом.

UPDATE vtable2 AS v1
INNER JOIN vtable1 AS v2a ON v1.group_id = v2a.group_id AND (...conditions...)
LEFT OUTER JOIN vtable1 AS v2b ON v1.group_id = v2b.group_id
  AND v2a.score < v2b.score AND (...conditions...)
SET v1.buddy = v2.id
WHERE v2b.group_id IS NULL;

Вы должны продублироватьвсе остальные условия в выражении для внешнего соединения;Вы не можете поместить их в предложение WHERE.

0 голосов
/ 02 июня 2011

вы можете проверить с помощью числовой переменной

 SELECT v2.id FROM vtable1 v2
WHERE
v2.group_id = 1 AND
// 6 more basic comparisons
ORDER BY score DESC LIMIT 1

В любом случае, я думаю, что лучше использовать Join, но у меня нет схемы базы данных.
Может быть, у вас проблемы с индексом в вашей БД sql.

...