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 색인 이 실 효 된 것 에 관 한 자 료 는 다른 관련 글 을 주목 하 십시오!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Redash를 사용할 때 몰랐던 SQL을 쓰는 법을 배웠습니다.최근 redash에서 sql을 쓸 기회가 많고, 이런 쓰는 방법이 있었는지와 sql에 대해 공부를 다시하고 있기 때문에 배운 것을 여기에 씁니다. Redash란? 월별로 데이터를 표시하고 싶습니다 주별로 데이터를 표...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.