2014-01-19 1 views
1

특정 쿼리를 실행하는 파일 정렬을 피하기 위해 테이블에 대한 인덱스를 선택하도록 도와주십시오.파일 정렬 사용을 피하기 위해 인덱스 최적화

그래서, 두 개의 테이블 demo_userdemo_question이 있습니다 :

CREATE TABLE `demo_user` (
    `id` INT(11) NOT NULL AUTO_INCREMENT, 
    `name` VARCHAR(50) NOT NULL, 
    `age` INT(11) NOT NULL, 
    PRIMARY KEY (`id`), 
    INDEX `age` (`age`) 
) 
COLLATE='utf8_general_ci' 
ENGINE=InnoDB; 

CREATE TABLE `demo_question` (
    `id` INT(11) NOT NULL AUTO_INCREMENT, 
    `userId` INT(11) NOT NULL, 
    `createdAt` DATETIME NOT NULL, 
    `question` VARCHAR(50) NOT NULL, 
    PRIMARY KEY (`id`), 
    INDEX `userId` (`userId`), 
    INDEX `createdAt` (`createdAt`), 
    CONSTRAINT `FK_demo_question_demo_user` FOREIGN KEY (`userId`) REFERENCES  `demo_user` (`id`) 
) 
COLLATE='utf8_general_ci' 
ENGINE=InnoDB; 

일부 샘플 데이터 :

select * 
from demo_question q 
left join demo_user u on q.userId = u.id 
where u.age >= 20 and u.age <= 30 
order by q.createdAt desc 

: 나는 다음과 같은 쿼리를 실행하려고이 테이블에

INSERT INTO `demo_user` VALUES ('u1', 20); 
INSERT INTO `demo_user` VALUES ('u2', 25); 
INSERT INTO `demo_user` VALUES ('u3', 27); 
INSERT INTO `demo_user` VALUES ('u4', 33); 
INSERT INTO `demo_user` VALUES ('u5', 19); 
INSERT INTO `demo_question` VALUES (2, '2014-01-19 15:17:13', 'q1'); 
INSERT INTO `demo_question` VALUES (3, '2014-01-19 15:17:43', 'q2'); 
INSERT INTO `demo_question` VALUES (5, '2014-01-19 15:17:57', 'q3'); 

이 쿼리에 대한 설명은 결과를 0123으로 정렬하는 동안 filesort를 감지합니다. 91,열

+----+-------------+-------+------+---------------+------+---------+------+------+---------------------------------+ 
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra       | 
+----+-------------+-------+------+---------------+------+---------+------+------+---------------------------------+ 
| 1 | SIMPLE  | q  | ALL | userId  | NULL | NULL | NULL | 3 | Using temporary; Using filesort | 
| 1 | SIMPLE  | u  | ALL | PRIMARY,age | NULL | NULL | NULL | 5 | Using where; Using join buffer | 
+----+-------------+-------+------+---------------+------+---------+------+------+---------------------------------+ 

그래서 내 질문 : 같은 쿼리를 실행하는 동안 두 테이블의 행 더 많은이 때 성능이 저하하기 때문에, filesorting을 방지하기 위해 무엇을 할 수 있는지?

+0

mysql이 너무 어리 석다는 것을 알기 위해 왼쪽 결합이 아닌 내부 결합으로 시도하십시오. –

+0

@Denis 안타깝게도 내부 조인은 아무 것도 바뀌지 않습니다 – gatisl

+0

demo_question에서 2 개의 인덱스가 아니라 두 개의 열을 inndex에 넣으십시오. 즉 INDEX'userId' ('userId')는 INDEX'userId' ('userId','createdAt')가됩니다 –

답변

1

이미이 쿼리에서 사용할 수있는 모든 인덱스가 있습니다. 두 가지 문제가 있습니다. 첫째, 이것은 분명히 왼쪽 조인이 아니며 내부 조인이므로 옵티 마이저가 의도 한 바를 실현하더라도 (즉, 다르게 표현 함에도 불구하고 이것이 사실임을 이해해야합니다.) 쿼리를 변경해도 쿼리 계획이 변경되지 않는 이유를 설명합니다.

두 번째 문제점은 옵티마이 저가 더 큰 데이터 세트에서 사용되는 것과 동일한 작은 데이터 세트로 플랜을 선택할 것이라고 기대할 수 없다는 것입니다.

옵티마이 저는 "비용"에 대한 결정을 내리고 작은 데이터 세트의 인덱스를 사용하는 비용은 상대적으로 높다고 가정하기 때문에 지금은 추측 할 수 없지만 나중에는 그렇지 않을 것입니다 ... 여기서 얻는 계획은 데이터 세트가 변경 될 때 변경됩니다.

+0

좋은 설명. 시간 내 줘서 고마워. – gatisl

관련 문제