MySQL - Почему безопасный режим обновления блокирует эту команду UPDATE? - PullRequest
0 голосов
/ 02 июня 2019

У меня есть таблица actor, которая выглядит следующим образом:

| actor_id | first_name | last_name | last_update         |
+----------+------------+-----------+---------------------+
| 1        | Jack       | Nicholson | 2019-06-02 00:00:00 |

Столбец actor_id - это первичный ключ с автоматическим приращением.

Когда я пытаюсь обновить таблицу какИтак:

UPDATE actor
SET last_name = 'foo'
WHERE last_update > '2019-06-02 00:00:00';

Я заблокирован безопасным режимом обновления MySQL с этой ошибкой:

Код ошибки: 1175. Вы используете безопасный режим обновления и пытались обновить таблицубез ГДЕ, который использует столбец KEY.Чтобы отключить безопасный режим, переключите параметр в «Предпочтения» -> «Редактор SQL» и переподключите.

Действительно, столбец last_update не является столбцом KEY, поэтому на основе этот ответ SO Iпридумали следующий обходной путь:

CREATE TEMPORARY TABLE IF NOT EXISTS ids AS (SELECT actor_id FROM actor WHERE last_update > '2019-06-02 00:00:00');

UPDATE actor
SET last_name = 'foo'
WHERE actor_id IN (SELECT actor_id FROM ids);

Но снова я заблокирован с ошибкой 1175.

Почему безопасный режим обновления блокирует меня здесь?Можно ли обойти это без отключения безопасного режима обновления?

1 Ответ

2 голосов
/ 02 июня 2019

Вы можете обойти эту ошибку, сделав столбец столбцом KEY. Другими словами, создайте индекс (или ключ) для столбца.

mysql> set sql_safe_updates=ON;

mysql> UPDATE actor SET last_name = 'foo' WHERE last_update > '2019-06-02 00:00:00';
ERROR 1175 (HY000): You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column

mysql> alter table actor add key (last_update);
Query OK, 0 rows affected (0.04 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> UPDATE actor SET last_name = 'foo' WHERE last_update > '2019-06-02 00:00:00';
Query OK, 0 rows affected (0.00 sec)
Rows matched: 0  Changed: 0  Warnings: 0

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

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

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