приоритет первичного ключа и многостолбцовый индекс в MySQL?

0
CREATE TABLE student (                                  
  id int(11) NOT NULL AUTO_INCREMENT,                   
  name varchar(128) DEFAULT NULL,                 
  age int(11) NOT NULL,
  update_time timestamp NULL DEFAULT CURRENT_TIMESTAMP 
    ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (id),                                   
       KEY idx_name_age (name,age),                         
       KEY idx_name_age_update_time (name,age,update_time) 
     ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8

И я использую EXPLAIN чтобы получить некоторую информацию о том, как индексы работают в MySQL, и я обнаружил одну вещь, которая меня смутила, когда я выполняю sql следующим образом:

EXPLAIN 
  SELECT * FROM springboot.student
    WHERE id>1 AND id <5 AND NAME = 'tank' AND age =23 ;

И результат:

id   select_type   table     type     possible_keys    key            key_len   ref             rows  Extra        
------  -----------  -------  ------  ---------------------------------------------  ------------  -------  -----------  ------  -------------
1  SIMPLE       student  ref     PRIMARY,idx_name_age,idx_name_age_update_time  idx_name_age  391      const,const       1  Using where 

Интересно, почему это получилось для меня.

  • 0
    Что тебя смущает?
  • 0
    запутался, почему это делает путь неожиданным
Теги:

1 ответ

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

Там нет присущего приоритета. Вы влияете на оптимизатор SQL, но не можете его контролировать. И это на самом деле хорошо. Оптимизаторы на основе правил устарели уже довольно давно, а оптимизаторы с затратами - все это ярость.

Случается, что оптимизатор SQL [на основе затрат] создает план выполнения, который зависит от многих параметров. Например:

  • Размер таблицы.
  • Представлены индексы.
  • Распределения значений каждого столбца.
  • Селективность условий фильтрации.
  • Как текущая статистика таблицы.
  • и т.п.

Кажется, вы хотите, чтобы таблица была прочитана индексом с использованием первичного ключа. Переведенный на термины оптимизатора, вы хотите:

  • Доступ: по индексу первичного ключа, используя сканирование диапазона индексов.
  • Фильтрация: по NAME = 'tank' AND age = 23.

Однако оптимизатор решил по-другому:

  • Доступ: по индексу (name, age), используя индексный поиск.
  • Фильтрация: по индексу первичного ключа.

В целом поиск индексов намного быстрее, чем сканирование индексов. Возможно, именно поэтому оптимизатор выбрал второй.

Вы фактически измеряли время выполнения? Помните, что план - это не запрос. Измерение, измерение, измерение.

  • 0
    Интересно, почему это делает это по-другому
  • 0
    Я не понимаю вашего вопроса. Обычно равенство = более ценно (читай поиск индекса ), а не неравенство > (читай сканирование диапазона индекса ), когда дело доходит до поиска по индексу.
Показать ещё 5 комментариев

Ещё вопросы

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