【发布时间】:2011-04-23 22:52:07
【问题描述】:
这个查询:
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'
正确使用 Donation.order_line_id 和 Lineitem.id 索引,显示在此 EXPLAIN 输出中:
但是,这个查询,它只包含另一个字段:
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 字段都已编入索引,但我无法弄清楚将此字段添加到选定字段列表中如何导致索引被删除。
根据 James C 的要求,以下是表定义:
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。希望这表明一些有用的信息?
我在想 USE INDEX 可能会解决问题,但我使用的 ORM 让这有点棘手,我不明白为什么它不会在 JOIN 时获取正确的索引名称索引字段?!?
感谢您的智慧!
【问题讨论】:
标签: mysql sql optimization