이 쿼리MySQL 전문가 : 왜 2 개의 쿼리가 서로 다른 '설명'인덱스 사용 결과를 제공합니까?
가explain
SELECT `Lineitem`.`id`, `Donation`.`id`, `Donation`.`order_line_id`
FROM `order_line` AS `Lineitem`
LEFT JOIN `donations` AS `Donation`
ON (`Donation`.`order_line_id` = `Lineitem`.`id`)
WHERE `Lineitem`.`session_id` = '1'
올바르게 EXPLAIN이에 도시 Donation.order_line_id
및 Lineitem.id
인덱스를 사용하여 출력 :
id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE Lineitem ref session_id session_id 97 const 1 Using where; Using index 1 SIMPLE Donation ref order_line_id order_line_id 4 Lineitem.id 2 Using index
그러나, 단순히 다른 필드를 포함하고이 질의 :
explain
SELECT `Lineitem`.`id`, `Donation`.`id`, `Donation`.`npo_id`,
`Donation`.`order_line_id`
FROM `order_line` AS `Lineitem`
LEFT JOIN `donations` AS `Donation`
ON (`Donation`.`order_line_id` = `Lineitem`.`id`)
WHERE `Lineitem`.`session_id` = '1'
을
Donation
테이블에서 인덱스를 사용하지 않음을 보여줍니다.
id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE Lineitem ref session_id session_id 97 const 1 Using where; Using index 1 SIMPLE Donation ALL order_line_id NULL NULL NULL 3
표의 모든 _id
필드의 색인이 생성되지만이 필드를 선택한 필드 목록에 추가하면 색인이 삭제되는 이유를 알 수 없습니다.
CREATE TABLE `donations` (
`id` int(10) unsigned NOT NULL auto_increment,
`npo_id` int(10) unsigned NOT NULL,
`order_line_detail_id` int(10) unsigned NOT NULL default '0',
`order_line_id` int(10) unsigned NOT NULL default '0',
`created` datetime default NULL,
`modified` datetime default NULL,
PRIMARY KEY (`id`),
KEY `npo_id` (`npo_id`),
KEY `order_line_id` (`order_line_id`),
KEY `order_line_detail_id` (`order_line_detail_id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8
CREATE TABLE `order_line` (
`id` bigint(20) unsigned NOT NULL auto_increment,
`order_id` bigint(20) NOT NULL,
`npo_id` bigint(20) NOT NULL default '0',
`session_id` varchar(32) collate utf8_unicode_ci default NULL,
`created` datetime default NULL,
PRIMARY KEY (`id`),
KEY `order_id` (`order_id`),
KEY `npo_id` (`npo_id`),
KEY `session_id` (`session_id`)
) ENGINE=InnoDB AUTO_INCREMENT=23 DEFAULT CHARSET=utf8
가 나는 또한 일부는 기수에 대한 책을 읽은했고, 모두 Donations.npo_id
및 Donations.order_line_id
는 2의 카디널리티는 희망이 무엇인가를 알 수있을 것 같습니다 :
제임스 C의 요청에 따라, 여기에 테이블 정의는 유능한?
USE INDEX
이 문제를 해결할 수 있다고 생각하지만, 약간 까다로울 수있는 ORM을 사용하고 있는데 왜 JOIN이 구체적으로 이름을 지정할 때 올바른 색인을 얻지 못하는지 이해하지 못합니다. 인덱싱 된 필드?!?
양해 해 주셔서 감사합니다.
실제로 이것은 100 % 올바르지 않을 수 있습니다. 당신은 테이블에 대한'SHOW CREATE TABLE'을 추가 할 수 있습니까? 그리고 전체'EXPLAIN' 출력을 주시겠습니까? –
이유를 이해할 수는 없지만 두 번째 인덱스를 추가하면됩니다.이 3 개의 ID는 모두 색인 생성되었습니다. 왜 order_line_id 색인이 무시되는 경우 이러한 ID로 구성된 색인을 생성합니까? – iopener
I think * 옵티마이 저가 단일 인덱스 사용에 이점이 없다고 판단했기 때문에 이러한 상황이 발생했습니다. 나는 테이블의 크기가 커짐에 따라 이것을 계속 지켜 볼 것입니다. 감사! – iopener