MySQL игнорирует Force Index для запроса на удаление, но не для эквивалентного запроса на выбор

Я очень смущен и расстроен здесь -

У меня есть таблица (table1), которая огромна.

Я пытаюсь выполнить запрос на удаление на основе другой таблицы. Оптимизатор запросов не использует соответствующий индекс, поэтому я пытаюсь заставить его

delete table1 
FROM table1
FORCE INDEX FOR JOIN (index1)  
inner JOIN table2  
where
table1.field1=table2.field1
and
table1.field2=table2.field2
and
date(table1.startdatetime)=table2.reportdate;

Эквивалентный выбор выглядит следующим образом:

SELECT * 
FROM table1
FORCE INDEX FOR JOIN (index1)  
inner JOIN table2  
where
table1.field1=table2.field1
and
table1.field2=table2.field2
and
date(table1.startdatetime)=table2.reportdate;

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

«Объяснить» из выбора:

1   SIMPLE  table2 index    idx1    idx1    55      1456    Using where; Using index
1   SIMPLE  table1 ref  index1 index1 51    table2.field1,table2.field2 508 **Using index condition**

Но объяснение удаления выглядит следующим образом:

# id, select_type, table, type, possible_keys, key, key_len, ref, rows, Extra
1, SIMPLE, table2, index, idx1, idx1, 55, , 1456, Using where; Using index
1, SIMPLE, table1, ref, index1, index1, 51, table2.field1,table2.field2, 508, Using where

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

Как я могу заставить удаление также использовать индекс?

Благодарю вас!


person Stumbling Through Data Science    schedule 25.01.2019    source источник
comment
Часто бывает быстрее создать новую таблицу, сохранив только нужные данные, затем удалить исходную таблицу, а затем переименовать новую таблицу.   -  person Strawberry    schedule 26.01.2019
comment
Это не очень практично, когда рассматриваемая таблица составляет 1 ТБ, а удаленная сумма составляет менее 1% от нее. Спасибо за идею, хотя   -  person Stumbling Through Data Science    schedule 26.01.2019
comment
Ну, это практично, если это быстрее   -  person Strawberry    schedule 26.01.2019
comment
Трудно помочь вам без SHOW CREATE TABLE для обеих таблиц и версии MySQL, которую вы используете.   -  person Rick James    schedule 27.01.2019


Ответы (2)


Подсказки индекса применяются только к операторам SELECT. (Они принимаются синтаксическим анализатором для операторов UPDATE, но игнорируются и не действуют.)

из официальной документации

Несмотря на то, что это специально не вызывается, я предполагаю, что DELETE подпадает под то, как обрабатывается UPDATE, а не SELECT.

person Uueerdo    schedule 25.01.2019
comment
Спасибо... какой удивительно глупый и случайный способ реализации функциональности. - person Stumbling Through Data Science; 26.01.2019
comment
В более новых версиях оптимизатор стал общим для операторов SELECT и DML. - person Rick James; 27.01.2019

Неэффективность может быть

date(table1.startdatetime)=table2.reportdate

Нельзя использовать индекс startdatetime, потому что он скрыт внутри вызова функции. Обычно лучше сделать:

    table1.startdatetime >= table2.reportdate
AND table1.startdatetime  < table2.reportdate + INTERVAL 1 DAY
person Rick James    schedule 27.01.2019