У меня есть две таблицы с именами ny_clean (3454602 записей) и pickup_0_ids_temp_table (2739268 записей), у которых есть столбец id CHAR (11), который является первичным ключом, и поверх него индекс BTREE (MySQL 5.7).
Столбец "id" в pickup_0_ids_temp_table является подмножеством ny_clean, и я хочу получить результат ny_clean без значений идентификатора из pickup_0_ids_temp_table.
Вариант 1:
EXPLAIN
SELECT *
FROM pickup_0_ids_temp_table as t
JOIN ny_clean as n
ON n.id != t.id;
+----+-------------+----------+------------+-------+---------------+-------------------+---------+------+---------+----------+-----------------------------------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+----------+------------+-------+---------------+-------------------+---------+------+---------+----------+-----------------------------------------------------------------+
| 1 | SIMPLE | t | NULL | index | NULL | PRIMARY | 11 | NULL | 2734512 | 100.00 | Using index |
| 1 | SIMPLE | ny_clean | NULL | index | NULL | btree_pk_ny_clean | 11 | NULL | 3445904 | 90.00 | Using where; Using index; Using join buffer (Block Nested Loop) |
+----+-------------+----------+------------+-------+---------------+-------------------+---------+------+---------+----------+-----------------------------------------------------------------+
Вариант 2:
EXPLAIN
SELECT *
FROM ny_clean as n
WHERE n.id NOT IN (
SELECT id
FROM pickup_0_ids_temp_table);
+----+--------------------+-------------------------+------------+-----------------+------------------------+---------+---------+------+---------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+--------------------+-------------------------+------------+-----------------+------------------------+---------+---------+------+---------+----------+-------------+
| 1 | PRIMARY | n | NULL | ALL | NULL | NULL | NULL | NULL | 3445904 | 100.00 | Using where |
| 2 | DEPENDENT SUBQUERY | pickup_0_ids_temp_table | NULL | unique_subquery | PRIMARY,btree_pickup_0 | PRIMARY | 11 | func | 1 | 100.00 | Using index |
+----+--------------------+-------------------------+------------+-----------------+------------------------+---------+---------+------+---------+----------+-------------+
Затем я использую один из вариантов внутри этого более крупного запроса
EXPLAIN
INSERT INTO y
SELECT id, pickup_longitude, pickup_latitude
FROM x
JOIN
(OPTION 1 OR 2) as z
ON z.id = x.id;
Когда я использовал вариант 1 внутри более крупного запроса, он выполнялся в течение двух дней и не был завершен. Вариант 2, с другой стороны, сделал работу менее чем за 30 минут
Мой вопрос: почему это так?
Следуя документации MySQL (https://dev.mysql.com/doc/refman/5.7/en/subquery-materialization.html), я подозреваю, что это связано с материализацией подзапроса, но как мне это проверить?
И я неправильно интерпретирую вывод EXPLAIN? Поскольку, исходя из этого, я ожидаю, что вариант 1 будет быстрее, поскольку он использует индекс для обеих таблиц
Или это нужно сделать с большим запросом?
Заранее спасибо