Очень маленькие таблицы MySQL игнорируют индексы?

0

После включения log_queries_not_using_indexes я заметил, что один запрос быстро заполнял медленный журнал запросов:

SELECT abc.* FROM abc WHERE abc.id NOT IN ( SELECT DISTINCT abc_id FROM zyx WHERE id = 12345 );

abc очень мало, всего 3 строки данных. zyx относительно велик с более чем 100 000 строк данных.

abc.id есть индекс, но когда я EXPLAIN запрос, индекс не указан ни под key ни с possible_keys key. Это объясняет, почему запрос отображается в медленном журнале, но мой вопрос в том, почему он не использует индекс?

Короче говоря, у меня есть два вопроса:

  1. Стоит ли маленьким таблицам игнорировать индексы? Я мог понять, почему, это не экономит много времени, чтобы использовать индекс в 3 строках данных.
  2. Если да, то как я могу предотвратить этот запрос от наводнения моего медленного журнала запросов?

Спасибо за ваше время! :)

Дополнительная информация, если необходимо:

Я запустил ANALYZE TABLE abc как я читал, иногда исправляет проблему. Я также перезапустил MariaDB с момента добавления индекса.

Больше EXPLAIN: select_type = PRIMARY, table = abc, type = ALL, possible_keys = NULL, key = NULL, key_len = NULL, ref = NULL, rows = 3, Extra = Using where

  • 0
    Это очень отличается от того, что отсутствие индекса для небольшой таблицы приводит к замедлению запроса. Есть ли индекс на zyx.id ?
  • 1
    @Uueerdo ОП не подразумевает, что запрос медленный; просто он появляется в журнале медленных запросов. (Который регистрирует все запросы, отвечающие определенным критериям, а не только те, которые на самом деле занимают много времени.)
Показать ещё 2 комментария
Теги:
mariadb

2 ответа

2
Лучший ответ

Стоит ли маленьким таблицам игнорировать индексы?

Да. Когда вся таблица может быть прочитана в одном доступе на диске, нет смысла выполнять отдельный доступ к диску для чтения индекса.

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

Отключите log_queries_not_using_indexes. Это одна из причин, по которой она не включена по умолчанию.

1

NOT IN ( SELECT... ) очень плохо оптимизирован, особенно в старых версиях.

Перейдите к следующему:

SELECT  abc.*
    FROM  abc
    LEFT JOIN  zyx  ON zyx.abc_id = abc.id
    WHERE  zyx.abc_id IS NULL;
AND  zyx.id = 12345 ;

Для zyx имеют либо INDEX(id, abc_id) либо INDEX(abc_id, id)

Если zyx.id является PRIMARY KEY, ваш запрос не имеет большого смысла - зачем тестировать одну строку (12345)?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню