Пример, объясняющий самый левый принцип сопоставления Mysql.

теоретические знания

Самый левый принцип сопоставления : самый левый является первым, и любой непрерывный индекс, начинающийся с самого левого, может быть сопоставлен. В то же время, когда встречается запрос диапазона (>, <, between, like), сопоставление останавливается.

Нижний слой индекса — это дерево B+, поэтому, конечно, совместный индекс — это все еще дерево B+, но количество ключевых значений объединенного индекса не одно, а
несколько. Построение дерева B+ может быть построено только на основе одного значения, поэтому база данных строит дерево B+ на основе крайнего левого поля объединенного индекса.
вставьте сюда описание изображения
https://www.bilibili.com/video/BV1Ca411d7RM?p=6&vd_source=aa05fb870c31dea69394e3d1beb9e83c
Чтобы узнать больше о msyql, вы можете прослушать этот урок

Пример: если вы создаете совместный индекс (a,b), то его дерево индексов выглядит так: вы
вставьте сюда описание изображения
можете видеть, что значения a расположены по порядку: 1, 1, 2, 2, 3, 3 , а значения b равны 1, 2, 1, 4, 1, 2 в произвольном порядке. Таким образом, условие запроса b = 2 не может использовать индекс, поскольку объединенный индекс сначала сортируется по a, а b неупорядочен.

В то же время мы также можем обнаружить, что при равенстве значений a значения b располагаются по порядку, но этот порядок относительный. Поэтому, когда крайний левый принцип сопоставления встречает запрос диапазона, он останавливается, а остальные поля не могут быть проиндексированы. Например, a = 1 и b = 2 Оба поля a и b могут использовать индексы, поскольку b относительно упорядочено, когда определяется значение a, и a>1 и b=2, поле a может соответствовать индексу, но значение b Нет, так как значение a представляет собой диапазон, в котором b неупорядочено.
вставьте сюда описание изображения

пример кода

Создайте таблицу Student в базе данных mytest

use mytest;

drop table if exists `student`;
create table `student`
(
  `id`      int not null auto_increment,
  `name`    varchar(50) not null,
  `number`  varchar(20) not null,
  `address` varchar(100),
  `age`     int default 0,
  primary key (`id`)
)Engine=InnoDB DEFAULT CHARSET=utf8;

insert into student (`name`, `number`, `address`, `age`)
values
("马云", "18000001", "浙江省杭州市余杭区", 55),
("马化腾", "18000002", "广东省深圳市南山区", 50),
("张一鸣", "18000003", "北京市海淀区", 38),
("王兴", "18000004", "北京市朝阳区", 40),
("李彦宏", "18000005", "北京市海淀区", 45),
("程维", "18000006", "北京市海淀区", 42),
("雷军", "18000007", "北京市朝阳区", 54),
("刘备", "18000008", "四川省成都市青羊区", 60),
("诸葛亮", "18000009", "四川省成都市武侯区", 43),
("关羽", "18000010", "湖北省荆州市荆州区", 58),
("张飞", "18000011", "四川省阆中市", 56),
("曹操", "18000012", "河南省洛阳市老城区", 63),
("孙权", "18000013", "江苏省南京市建邺区", 49),
("李世民", "18000014", "陕西省西安市长安区", 38),
("李隆基", "18000015", "陕西省西安市长安区", 28),
("朱元璋", "18000016", "江苏省南京市玄武区", 61),
("朱棣", "18000017", "北京市东城区", 39);

вставьте сюда описание изображения

использование объяснения

вставьте сюда описание изображения

Что касается того, использует ли запрос SQL индекс, используйте ключевое слово объяснения для запроса производительности инструкции SQL.Подробности см. в этой статье
https://blog.csdn.net/qq_27198345/article/details/116382587 .

Запросить неиндексированную информацию

EXPLAIN SELECT name, address FROM student WHERE address LIKE "北京市%";

вставьте сюда описание изображения
Мы видим, что индекс не используется, тип — ALL, а строк запроса — 17, что указывает на полное сканирование таблицы.

Создайте единый индекс для таблицы Student

Создать индекс адресов

alter table student add index (address(9));

вставьте сюда описание изображения

Затем запросите анализ производительности

EXPLAIN SELECT name, address FROM student WHERE address LIKE "北京市%";

вставьте сюда описание изображения
Мы обнаружили, что у возможных_ключей есть адрес, а у фактического ключа нет! ! ! Этот момент отличается от сообщения в блоге, на которое я ссылаюсь.Могут быть разные версии mysql, моя 5.7. Этот блогер использует index. Этого достаточно, чтобы все поняли, и запрос будет быстрее при использовании индекса. И хотя имя находится впереди, адрес сзади не влияет на использование одного индекса. Это отличается от порядка совместного индекса. Ниже есть совместный индекс без id, обратите внимание на разницу.
вставьте сюда описание изображения

Создайте совместный индекс в таблице Student

CREATE UNIQUE INDEX uni_id_age_number ON student(id,age,number)

вставьте сюда описание изображения

Проверить совместный индекс

В моем немного менее строгом месте используется идентификатор первичного ключа в качестве общего индекса, потому что нижний слой mysql построит дерево B+ с идентификатором в качестве индекса по умолчанию, потому что идентификатор уже может различать каждую строку, поэтому даже если объединенный индекс используется, он будет использовать только индекс идентификатора для запроса. Каждый может понять, что это значит. Если в качестве общего индекса используется столбец без идентификатора, нижний слой будет генерировать объединенный индекс без идентификатора. Это также причина, по которой не рекомендуется индексировать данные с большим объемом данных в сотни миллионов. Но на самом деле все они удовлетворяют самому левому правилу соответствия. Если вы хотите провести эксперимент, вы можете вручную вставить еще один столбец для сравнения.

1 запрос на полное соответствие

EXPLAIN SELECT * FROM student WHERE id = 10 AND age = 58 AND number = 18000010

Используется индекс, а порядок нескольких условий поиска в предложении where заменяется, не влияя на результаты запроса, поскольку в Mysql есть оптимизатор запросов, который автоматически оптимизирует порядок запросов.Поскольку в качестве индекса используется идентификатор, используется только один индекс id, и комбинация бесполезна. Давайте попробуем посмотреть, есть ли какая-то разница в эффекте от неиспользования id в качестве общего индекса.
вставьте сюда описание изображения

Добавить столбец в качестве общего индекса

ALTER TABLE student ADD grade INT(4);

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

MySQL: вставьте новый столбец данных в существующую таблицу данных
https://blog.csdn.net/Yvettre/article/details/80239531.

вставьте сюда описание изображения

Создать совместный индекс (без идентификатора)

CREATE UNIQUE INDEX uni_age_number_grade ON student(age,number,grade)

вставьте сюда описание изображения

Когда полное значение соответствует запросу

Вместо использования id в качестве общего индекса используйте общий индекс

EXPLAIN SELECT * FROM student WHERE grade = 78 AND age = 58 AND number = 18000010

вставьте сюда описание изображения

2 при сопоставлении с левым столбцом

EXPLAIN SELECT * FROM student WHERE id = 10 
EXPLAIN SELECT * FROM student WHERE id = 10 AND age = 58 
EXPLAIN SELECT * FROM student WHERE id = 10 AND age = 58 AND number = 18000010

вставьте сюда описание изображения
вставьте сюда описание изображения
вставьте сюда описание изображения
Все они сопоставляются непрерывно, начиная с крайнего левого, с использованием индекса

Если вы напрямую запрашиваете возраст и номер, индекс не будет использоваться.

EXPLAIN SELECT * FROM student WHERE age = 58  

вставьте сюда описание изображения

EXPLAIN SELECT * FROM student WHERE number = 18000010

вставьте сюда описание изображения

EXPLAIN SELECT * FROM student WHERE age = 58 AND number = 18000010

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

Когда он не является непрерывным, используется только индекс идентификатора, ни возраст, ни число не используются

EXPLAIN SELECT * FROM student WHERE id = 10 AND number = 18000010

вставьте сюда описание изображения

EXPLAIN SELECT * FROM student WHERE age = 58 AND grade = 78

вставьте сюда описание изображения
Это также отличается, используя index. Каждая версия mysql немного отличается.
вставьте сюда описание изображения

3 соответствует префиксу столбца

Это нормально. Если столбец является символьным типом, его правило сравнения состоит в том, чтобы сначала сравнить первый символ строки. Строка с меньшим первым символом будет меньше. Если первый символ двух строк одинаков, то сравнить второй символ, строка с меньшим вторым символом меньше и т. д., сравнить строки.

Если a является символьным типом, при сопоставлении префикса используется индекс, а суффикс и инфикс могут сканироваться только во всей таблице.

select * from table_name where a like 'As%'; //前缀都是排好序的,走索引查询
select * from table_name where  a like '%As'//全表查询
select * from table_name where  a like '%As%'//全表查询

Создайте таблицу user1, если вы не укажете имя в качестве ключа, индекс не будет использоваться.

CREATE TABLE `user1` (
  `id` INT NOT NULL AUTO_INCREMENT COMMENT '主键',
  `name` VARCHAR(255) DEFAULT NULL COMMENT '姓名',
  `age` INT DEFAULT NULL COMMENT '年龄',
  PRIMARY KEY (`id`)
  #KEY `idx_name` (`name`) ##删除这句话like 不能使用索引
) ENGINE=INNODB COMMENT='用户表';

вставьте сюда описание изображения
Индекс используется после добавления имени в качестве индекса.

вставьте сюда описание изображения

4 Запрос диапазона соответствия

select * from table_name where  a > 1 and a < 3

Запрос диапазона можно выполнить для крайнего левого столбца.

select * from table_name where  a > 1 and a < 3 and b > 1;

Когда поиск по диапазону выполняется по нескольким столбцам одновременно, индекс дерева B+ используется только тогда, когда поиск по диапазону выполняется по крайнему левому столбцу индекса, то есть только a использует индекс, а b не упорядочен в диапазоне. из 1<a<3. Индексы использовать нельзя. После нахождения 1<a<3 записей можно продолжить фильтрацию поэлементно только по условию b > 1

5 Точное совпадение диапазона столбца с другим столбцом

Если левый столбец является точным поиском, правый столбец может выполнять поиск диапазона

select * from table_name where  a = 1 and b > 3;

В случае a=1 b упорядочивается, и поиск по диапазону использует объединенный индекс

6 сорт

Обратный порядок не использует индекс
вставьте сюда описание изображения

Supongo que te gusta

Origin blog.csdn.net/qq_41398619/article/details/126886082
Recomendado
Clasificación