GOOGLE ADS

Montag, 2. Mai 2022

Wie man ein effizientes UPDATE wie mein SELECT in MariaDB macht

Hintergrund

Ich habe eine kleine Tabelle mit 10 Zeilen aus einem vorherigen SELECT erstellt, das bereits ausgeführt wurde (SavedAnimals).

Ich habe eine riesige Tabelle (Tiere), die ich mit den Zeilen mit derselben ID wie jede Zeile in meiner neuen Tabelle AKTUALISIEREN möchte.

Was ich bisher probiert habe

Ich kann schnell die gewünschten Zeilen aus der großen Tabelle wie folgt auswählen:

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 | |
+------+--------------+-------------------------------+--------+---------------+---------+---------+----------------------------------------------------------+------+-------------+

Aber der "gleiche" Befehl auf dem UPDATE ist nicht schnell:

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)

Der UPDATE-Befehl wird nie beendet, wenn ich ihn ausführe.

FRAGE

Wie kann ich mariaDB mit dem materialisierten select_type auf dem UPDATE ausführen, wie es auf dem SELECT der Fall ist?

ODER

Gibt es einen völlig separaten Weg, wie ich das angehen sollte, der schnell wäre?

Anmerkungen

Version: 10.3.23-MariaDB-log


Lösung des Problems

Verwenden Sie JOINstatt WHERE...IN. MySQL optimiert sie tendenziell besser.

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

Keine Kommentare:

Kommentar veröffentlichen

Warum werden SCHED_FIFO-Threads derselben physischen CPU zugewiesen, obwohl CPUs im Leerlauf verfügbar sind?

Lösung des Problems Wenn ich das richtig verstehe, versuchen Sie, SCHED_FIFO mit aktiviertem Hyperthreading ("HT") zu verwenden, ...