приоритет первичного ключа и многостолбцовый индекс в MySQL? - PullRequest
0 голосов
/ 27 июня 2018
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 

Интересно, почему у меня это есть?

1 Ответ

0 голосов
/ 27 июня 2018

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

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

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

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

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

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

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

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

Вы действительно измеряли время выполнения? Помните, что план не является запросом. Мера, мера, мера.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...