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
Интересно, почему это получилось для меня.
Там нет присущего приоритета. Вы влияете на оптимизатор SQL, но не можете его контролировать. И это на самом деле хорошо. Оптимизаторы на основе правил устарели уже довольно давно, а оптимизаторы с затратами - все это ярость.
Случается, что оптимизатор SQL [на основе затрат] создает план выполнения, который зависит от многих параметров. Например:
Кажется, вы хотите, чтобы таблица была прочитана индексом с использованием первичного ключа. Переведенный на термины оптимизатора, вы хотите:
NAME = 'tank' AND age = 23
.Однако оптимизатор решил по-другому:
(name, age)
, используя индексный поиск.В целом поиск индексов намного быстрее, чем сканирование индексов. Возможно, именно поэтому оптимизатор выбрал второй.
Вы фактически измеряли время выполнения? Помните, что план - это не запрос. Измерение, измерение, измерение.
=
более ценно (читай поиск индекса ), а не неравенство >
(читай сканирование диапазона индекса ), когда дело доходит до поиска по индексу.