如何在 MariaDB 中像我的 SELECT 一样进行高效的更新

How to make an efficient UPDATE like my SELECT in MariaDB

背景

我从之前的 SELECT 已经 运行 (SavedAnimals) 做了一个 10 行的小 table。

我有一个巨大的 table(动物),我想使用与我的新 table.

中每一行具有相同 ID 的行进行更新

到目前为止我尝试了什么

我可以像这样从大 table 快速 SELECT 所需的行:

mysql> EXPLAIN SELECT * FROM animals WHERE ignored=0 and id IN (SELECT animal_id FROM SavedAnimals);

+------+--------------+-------------------------------+--------+---------------+---------+---------+----------------------------------------------------------+------+-------------+
| id   | select_type  | table                         | type   | possible_keys | key     | key_len | ref                                                      | rows | Extra       |
+------+--------------+-------------------------------+--------+---------------+---------+---------+----------------------------------------------------------+------+-------------+
|    1 | PRIMARY      | <subquery2>                   | ALL    | distinct_key  | NULL    | NULL    | NULL                                                     |   10 |             |
|    1 | PRIMARY      | animals                       | eq_ref | PRIMARY       | PRIMARY | 8       | db_staging.SavedAnimals.animal_id |    1 | Using where |
|    2 | MATERIALIZED | SavedAnimals | ALL    | NULL          | NULL    | NULL    | NULL                                                     |   10 |             |
+------+--------------+-------------------------------+--------+---------------+---------+---------+----------------------------------------------------------+------+-------------+

但是 UPDATE 上的“相同”命令并不快:

mysql> EXPLAIN UPDATE animals SET ignored=1, ignored_when=CURRENT_TIMESTAMP WHERE ignored=0 and id IN (SELECT animal_id FROM SavedAnimals);
+------+--------------------+-------------------------------+-------+---------------+---------+---------+------+----------+-------------+
| id   | select_type        | table                         | type  | possible_keys | key     | key_len | ref  | rows     | Extra       |
+------+--------------------+-------------------------------+-------+---------------+---------+---------+------+----------+-------------+
|    1 | PRIMARY            | animals                       | index | NULL          | PRIMARY | 8       | NULL | 34269464 | Using where |
|    2 | DEPENDENT SUBQUERY | SavedAnimals | ALL   | NULL          | NULL    | NULL    | NULL |       10 | Using where |
+------+--------------------+-------------------------------+-------+---------------+---------+---------+------+----------+-------------+
2 rows in set (0.00 sec)

如果我 运行 UPDATE 命令永远不会完成。

问题

如何像在 SELECT 上那样在 UPDATE 上使用 Materialized select_type 制作 mariaDB 运行?

有没有一种完全独立的方法可以快速解决这个问题?

备注

版本:10.3.23-MariaDB-log

使用 JOIN 而不是 WHERE...IN。 MySQL 倾向于更好地优化它们。

UPDATE animals AS a
JOIN SavedAnimals AS sa ON a.id = sa.animal_id
SET a.ignored=1, a.ignored_when=CURRENT_TIMESTAMP
WHERE a.ignored = 0

您应该会发现 EXISTS 子句比 IN 子句更有效。例如:

UPDATE animals a
SET a.ignored = 1, 
    a.ignored_when = CURRENT_TIMESTAMP
WHERE a.ignored = 0
  AND EXISTS (SELECT * FROM SavedAnimals sa WHERE sa.animal_id = a.id)