Что делает MySQL, если вы пытаетесь обновить запрашиваемую таблицу? - PullRequest
2 голосов
/ 12 января 2009

У меня очень медленный запрос, который мне нужно время от времени запускать в базе данных MySQL.

Я обнаружил, что попытки обновить запрашиваемую таблицу блокируются до завершения запроса.

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

Итак, мой вопрос состоит из двух частей:

  1. Из любопытства, что именно MySQL делает в этой ситуации? Блокирует ли она таблицу на время запроса? Или попытаться заблокировать его перед обновлением?

  2. Есть ли способ, чтобы медленный запрос не блокировался? Я думаю, варианты могут быть:

    • Убить запрос при необходимости обновления.
    • Запустить запрос к копии таблицы, как это было непосредственно перед обновлением
    • Просто позвольте запросу ошибиться.

У кого-нибудь есть мысли по этому поводу?

Ответы [ 5 ]

5 голосов
/ 12 января 2009

Похоже, вы используете таблицу MyISAM, которая использует блокировку на уровне таблицы. В этом случае SELECT установит общую блокировку на столе. Затем UPDATE попытается запросить эксклюзивную блокировку и блокировку и дождаться завершения SELECT. Как только это будет сделано, ОБНОВЛЕНИЕ будет работать как обычно.

Блокировка MyISAM

Если вы переключились на InnoDB, то ваш SELECT не будет устанавливать блокировки по умолчанию. Нет необходимости изменять уровни изоляции транзакции, как рекомендовали другие (повторное чтение по умолчанию для InnoDB, и для вашего SELECT блокировки не будут установлены). ОБНОВЛЕНИЕ сможет работать в то же время. Многовариантность, которую использует InnoDB, очень похожа на то, как Oracle справляется с ситуацией. Единственный раз, когда SELECTs устанавливает блокировки, если вы работаете на уровне изоляции сериализуемых транзакций, у вас есть опция FOR UPDATE / LOCK IN SHARE MODE для запроса, или это часть некоторого оператора записи (такого как INSERT. ..SELECT) и вы используете двоичное ведение журнала на основе операторов.

Блокировка InnoDB

1 голос
/ 12 января 2009

Прежде всего вам нужно знать, какой движок вы используете (MySam или InnoDb).

Это явно проблема транзакции.

Взгляните на раздел 13.4.6. Синтаксис SET TRANSACTION в руководстве по mysql.

1 голос
/ 12 января 2009

Для целей оператора select вам, вероятно, следует ввести:
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
команда на соединение, которая заставляет последующие операторы выбора работать без блокировки.
Не используйте 'SELECT ... FOR UPDATE', так как это определенно блокирует строки таблицы, на которые влияет оператор select.
Полный список уровней выделения транзакций msql: в документах .

0 голосов
/ 12 января 2009

ОБНОВЛЕНИЕ LOW_PRIORITY .... может быть полезно - документы mysql не ясны, позволит ли это продолжить пользователю, запрашивающему обновление, и обновление произойдет, когда это возможно (что, как я думаю, происходит), или имеет ли пользователь ждать (что было бы хуже, чем сейчас ...), и я не могу вспомнить.

Какие типы таблиц вы используете? Если вы используете MyISAM, переключение на InnoDB (если вы можете - у него нет полнотекстовой индексации) открывает больше возможностей для такого рода вещей, поскольку оно поддерживает функции транзакций и блокировку на уровне строк.

0 голосов
/ 12 января 2009

Я не знаю MySQL, но это звучит как проблема транзакции. Вы должны иметь возможность установить тип транзакции на «Грязное чтение» в запросе выбора.

Это не обязательно даст вам правильные результаты. Но это не должно быть заблокировано.

Лучше было бы сделать первый запрос быстрее. Сделайте анализ и проверьте, можете ли вы ускорить его с правильными значениями и т. Д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...