Почти везде я читаю, что использование FORCE INDEX
сильно обескуражено, и я прекрасно понимаю и знаю почему - есть огромные шансы, что MySQL лучше знает, какие индексы выбрать, чем (средний) разработчик.
Однако недавно я нашел случай, когда FORCE INDEX
улучшил время выполнения в диапазоне 100 раз:
-
JOIN
на 4 таблицах - первая таблица содержит около 500 000 записей
- 2 таблицы
INNER JOIN
ed имеют более 1 milion records - В первой таблице есть поле под названием
published_date
, которое хранится какvarchar
в формате YMD (не может быть изменено наdatetime
) - нужен диапазон на
published_date
не более 5 000 записей - для этого запроса были необходимы другие
GROUP BY
иORDER BY
предложения по первой таблице в разных полях, чемpublished_date
Хотя я переписал запрос во многих отношениях, мне не удалось получить время выполнения меньше 130 секунд (с наивысшим значением более 700). После использования FORCE INDEX
с published_date
время выполнения опустилось ниже 5 секунд.
Мне потребовалось несколько дней, чтобы вспомнить о печально известной опции FORCE INDEX
.
Вопросы:
- Какие другие варианты использования вы нашли, где
FORCE INDEX
сохранили вас? - Есть ли у вас несколько лучших практик, когда вы рассматриваете использование
FORCE INDEX
?
Изменить - Обобщения: Я создал этот пост в блоге с вопросом здесь. Весь ответ, который вы предоставите, также появится там - с кредитами и всем необходимым.
Изменить 2
Я применил предложения, которые я получил в ваших комментариях (ANALYZE TABLE
и OPTIMIZE TABLE
), ниже приведен результат EXPLAIN
, примененный к запросу - к сожалению, выбор индекса не лучше:
1. без FORCE INDEX
на таблице с псевдонимом a
:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE am2 range PRIMARY,idx_meta_article idx_meta_article 4 NULL 275228 Using where; Using index; Using temporary; Using f...
1 SIMPLE a eq_ref PRIMARY,serial_issue_date_productid,pub_date,idx_d... PRIMARY 4 mydb_toto.am2.ArticleID 1 Using where
1 SIMPLE ai ref PRIMARY,idx_iso_article PRIMARY 4 mydb_toto.a.serial 11523 Using where; Using index
1 SIMPLE m range PRIMARY,meta_articles_type meta_articles_type 4 NULL 96 Using where
1 SIMPLE am eq_ref PRIMARY,idx_meta_article PRIMARY 8 mydb_toto.a.serial,mydb_toto.m.meta_id 1 Using where; Using index
2. с FORCE INDEX
на таблице с псевдонимом a
:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE a range pub_date pub_date 11 NULL 17679 Using where; Using temporary; Using filesort
1 SIMPLE am2 ref PRIMARY,idx_meta_article PRIMARY 4 mydb_toto.a.serial 21930 Using where; Using index
1 SIMPLE ai ref PRIMARY,idx_iso_article PRIMARY 4 mydb_toto.a.serial 11523 Using where; Using index
1 SIMPLE m range PRIMARY,meta_articles_type meta_articles_type 4 NULL 96 Using where
1 SIMPLE am eq_ref PRIMARY,idx_meta_article PRIMARY 8 mydb_toto.am2.ArticleID,mydb_toto.m.meta_id 1 Using where; Using index
3. после ANALYZE TABLE
, без FORCE INDEX
:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE am2 range PRIMARY,idx_meta_article idx_meta_article 4 NULL 275228 Using where; Using index; Using temporary; Using f...
1 SIMPLE a eq_ref PRIMARY,serial_issue_date_productid,pub_date,idx_d... PRIMARY 4 mydb_toto.am2.ArticleID 1 Using where
1 SIMPLE ai ref PRIMARY,idx_iso_article PRIMARY 4 mydb_toto.a.serial 11523 Using where; Using index
1 SIMPLE m range PRIMARY,meta_articles_type meta_articles_type 4 NULL 96 Using where
1 SIMPLE am eq_ref PRIMARY,idx_meta_article PRIMARY 8 mydb_toto.a.serial,mydb_toto.m.meta_id 1 Using where; Using index
4. после OPTIMIZE TABLE
, без FORCE INDEX
:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE am2 range PRIMARY,idx_meta_article idx_meta_article 4 NULL 275228 Using where; Using index; Using temporary; Using f...
1 SIMPLE a eq_ref PRIMARY,serial_issue_date_productid,pub_date,idx_d... PRIMARY 4 mydb_toto.am2.ArticleID 1 Using where
1 SIMPLE ai ref PRIMARY,idx_iso_article PRIMARY 4 mydb_toto.a.serial 11523 Using where; Using index
1 SIMPLE m range PRIMARY,meta_articles_type meta_articles_type 4 NULL 96 Using where
1 SIMPLE am eq_ref PRIMARY,idx_meta_article PRIMARY 8 mydb_toto.a.serial,mydb_toto.m.meta_id 1 Using where; Using index
5. после OPTIMIZE TABLE
и ANALYZE TABLE
, с FORCE INDEX
:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE a range pub_date pub_date 11 NULL 17679 Using where; Using temporary; Using filesort
1 SIMPLE am2 ref PRIMARY,idx_meta_article PRIMARY 4 mydb_toto.a.serial 21930 Using where; Using index
1 SIMPLE ai ref PRIMARY,idx_iso_article PRIMARY 4 mydb_toto.a.serial 11523 Using where; Using index
1 SIMPLE m range PRIMARY,meta_articles_type meta_articles_type 4 NULL 96 Using where
1 SIMPLE am eq_ref PRIMARY,idx_meta_article PRIMARY 8 mydb_toto.am2.ArticleID,mydb_toto.m.meta_id 1 Using where; Using index