MySQL 인덱스 가 실 효 된 전형 적 인 사례

5723 단어 MySQL인덱스
전형 적 인 사례
두 장의 표 가 있 는데 표 구 조 는 다음 과 같다.

CREATE TABLE `student_info` (
  `id` int(11) NOT NULL,
  `name` varchar(10) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4

CREATE TABLE `student_score` (
  `id` int(11) NOT NULL,
  `name` varchar(10) DEFAULT NULL,
  `score` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
그 중 하 나 는 info 표 이 고,하 나 는 score 표 이 며,그 중 score 표 는 info 표 보다 score 필드 가 한 열 더 많 습 니 다.
데이터 삽입:

mysql> insert into student_info values (1,'zhangsan'),(2,'lisi'),(3,'wangwu'),(4,'zhaoliu');
Query OK, 4 rows affected (0.01 sec)
Records: 4  Duplicates: 0  Warnings: 0

mysql> insert into student_score values (1,'zhangsan',60),(2,'lisi',70),(3,'wangwu',80),(4,'zhaoliu',90);
Query OK, 4 rows affected (0.01 sec)
Records: 4  Duplicates: 0  Warnings: 0

mysql> select * from student_info;
+----+----------+
| id | name     |
+----+----------+
|  2 | lisi     |
|  3 | wangwu   |
|  1 | zhangsan |
|  4 | zhaoliu  |
+----+----------+
4 rows in set (0.00 sec)

mysql> select * from student_score ;
+----+----------+-------+
| id | name     | score |
+----+----------+-------+
|  1 | zhangsan |    60 |
|  2 | lisi     |    70 |
|  3 | wangwu   |    80 |
|  4 | zhaoliu  |    90 |
+----+----------+-------+
4 rows in set (0.00 sec)
우리 가 아래 의 문 구 를 진행 할 때:

mysql> explain select B.* 
       from 
       student_info A,student_score B 
       where A.name=B.name and A.id=1;
+----+-------------+-------+------------+-------+------------------+---------+---------+-------+------+----------+-------------+
| id | select_type | table | partitions | type  | possible_keys    | key     | key_len | ref   | rows | filtered | Extra       |
+----+-------------+-------+------------+-------+------------------+---------+---------+-------+------+----------+-------------+
|  1 | SIMPLE      | A     | NULL       | const | PRIMARY,idx_name | PRIMARY | 4       | const |    1 |   100.00 | NULL        |
|  1 | SIMPLE      | B     | NULL       | ALL   | NULL             | NULL    | NULL    | NULL  |    4 |   100.00 | Using where |
+----+-------------+-------+------------+-------+------------------+---------+---------+-------+------+----------+-------------+
2 rows in set, 1 warning (0.00 sec)
왜 B.name 에 색인 이 있 지만 계획 중의 두 번 째 selection 표 B 를 실행 할 때 색인 을 사용 하지 않 고 전체 표 로 스 캔 합 니까?
해석:
이 SQL 은 세 단 계 를 수행 합 니 다.
1.A.id=1 의 기록 을 먼저 걸 러 내 고 메 인 키 인덱스 를 사용 하여 LA 1 줄 만 스 캔 합 니 다.
2.LA 줄 에서 name 의 값"zhangsan"을 찾 습 니 다.
3.LA.name 의 값 에 따라 표 B 에서 찾 아 같은 값 zhangsan 을 찾 아 되 돌려 줍 니 다.
그 중에서 세 번 째 단 계 는 다음 과 같이 간소화 할 수 있다.
select * from student_score  where name=$LA.name
여기,LA 는 A 표 info 의 내용 이 고,info 표 의 문자 집합 은 utf8mb 4 이 며,B 표 score 표 의 문자 집합 은 utf 8 입 니 다.
그래서.
실행 할 때 하나의 utf 8 형식의 왼쪽 값 과 하나의 utf 8 mb 4 의 오른쪽 값 을 비교 하 는 것 과 같 습 니 다.utf 8 mb 4 는 utf 8 형식(긴 바이트 포함 짧 은 바이트)을 완전히 포함 하고 있 기 때문에 MySQL 은 utf 8 을 utf 8 mb 4 로 변환 합 니 다.
따라서 집행 한 셈 이다.

select * from student_score  where CONVERT(name USING utf8mb4)=$LA.name
색인 필드 가 암시 적 형식 변환 을 사용 하면 색인 이 효력 을 잃 고 MySQL 최적화 기 는 전체 표 스 캔 방식 으로 이 SQL 을 실행 한 다 는 것 을 알 고 있 습 니 다.
이 문 제 를 해결 하려 면 다음 과 같은 두 가지 방법 이 있다.
a.문자 집합 을 수정 합 니 다.
b.SQL 문 구 를 수정 합 니 다.
문자 집합 을 수정 하 는 방법 을 알려 줍 니 다:

mysql> alter table student_score modify name varchar(10)  character set utf8mb4 ;
Query OK, 4 rows affected (0.03 sec)
Records: 4  Duplicates: 0  Warnings: 0

mysql> explain select B.* from student_info A,student_score B where A.name=B.name and A.id=1;
+----+-------------+-------+------------+-------+------------------+----------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type  | possible_keys    | key      | key_len | ref   | rows | filtered | Extra |
+----+-------------+-------+------------+-------+------------------+----------+---------+-------+------+----------+-------+
|  1 | SIMPLE      | A     | NULL       | const | PRIMARY,idx_name | PRIMARY  | 4       | const |    1 |   100.00 | NULL  |
|  1 | SIMPLE      | B     | NULL       | ref   | idx_name         | idx_name | 43      | const |    1 |   100.00 | NULL  |
+----+-------------+-------+------------+-------+------------------+----------+---------+-------+------+----------+-------+
2 rows in set, 1 warning (0.01 sec)
SQL 을 수정 하 는 방법 은 여러분 스스로 시도 할 수 있 습 니 다.
첨부:일반적인 색인 이 실 효 된 경우
1.열 에 함 수 를 사용 하면 이 열의 색인 은 작용 하지 않 습 니 다.
2.열 에 대한 연산(+,-,*,/!등)이 열의 색인 은 작용 하지 않 을 것 이다.
3.어떤 경우 에 LIKE 작업 을 하면 이 열의 색인 이 작 동 하지 않 습 니 다.
4.어떤 경우 에 역방향 조작 을 사용 하면 이 열의 색인 은 작용 하지 않 습 니 다.
5.WHERE 에서 OR 를 사용 할 때 한 열 에 색인 이 없 으 면 다른 열의 색인 은 작용 하지 않 습 니 다.
6.암시 적 전환 으로 인해 색인 이 효력 을 잃 는 다 는 점 을 중시 해 야 한다.또한 개발 과정 에서 자주 저 지 르 는 실수 이기 도 한다.
7.not in,not exist 등 문 구 를 사용 할 때.
8.변 수 는 times 변 수 를 사용 하고 표 의 필드 는 date 변 수 를 사용 할 때 또는 반대 상황 을 사용 합 니 다.
9.B-tree 색인 is null 이 효력 을 잃 지 않 고 is not null 을 사용 할 때 효력 을 잃 습 니 다.비트 맵 색인 is null,is not null 은 모두 효력 을 잃 습 니 다.
10.연합 색인 is not null 은 만 든 색인 열(선후 구분 없 음)에서 모두 효력 을 잃 습 니 다.
이상 은 MySQL 색인 이 실 효 된 전형 적 인 사례 의 상세 한 내용 입 니 다.MySQL 색인 이 실 효 된 것 에 관 한 자 료 는 다른 관련 글 을 주목 하 십시오!

좋은 웹페이지 즐겨찾기