我正在尝试优化连接两个表的MYSQL查询的执行,如下所示:
CREATE TABLE `CPP` (
`RecordEntryType` varchar(7) NOT NULL default '',
`PositionNumber` mediumint(9) NOT NULL default '0',
`FundId` smallint(6) default NULL,
`QuantityHeld` decimal(14,2) default NULL,
`MarketValue` decimal(14,2) default NULL,
`PeriodBeginDate` date default NULL,
`PeriodEndDate` date NOT NULL default '0000-00-00',
PRIMARY KEY (`PositionNumber`,`PeriodEndDate`,`RecordEntryType`),
KEY `Index1` (`FundId`,`PeriodBeginDate`,`PeriodEndDate`),
KEY `FundId_idx` (`FundId`),
KEY `PeriodBeginDate_idx` (`PeriodBeginDate`),
KEY `PeriodEndDate_idx` (`PeriodEndDate`),
KEY `PositionNumber_id` (`PositionNumber`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `classification_entity_map` (
`entity_id` varchar(32) NOT NULL,
`entity_type` varchar(32) NOT NULL,
`scheme_id` int(11) NOT NULL,
`class_id` varchar(24) NOT NULL,
PRIMARY KEY (`entity_id`,`entity_type`,`scheme_id`),
KEY `fk_classification_entity_map_1` (`scheme_id`),
KEY `fk_class` (`class_id`),
CONSTRAINT `fk_class` FOREIGN KEY (`class_id`) REFERENCES `classification_hierarchy` (`external_id`),
CONSTRAINT `fk_scheme` FOREIGN KEY (`scheme_id`) REFERENCES `classification_schemes` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
select cpp.*, cem.class_id from cpp
LEFT JOIN classification_entity_map cem
ON cem.entity_id = cpp.PositionNumber and cem.entity_type = 'Security'
AND cem.scheme_id = 9901
WHERE cpp.RecordEntryType = 'CURRENT'
AND ( cpp.MarketValue != 0 OR cpp.QuantityHeld != 0 )
AND FundId = 28
AND cpp.PeriodEndDate = '2013-09-30';
问题是查询在mysql workbench(9.4秒)中花费的时间比预期的要长,因为它使用的是fk_classification_entity_map_1索引而不是classification_entity_map表中的主索引。 cpp有626,648行,cem有63,487行。
我怀疑这个问题与cem.entity_id&的数据类型有关。 cpp.PositionNumber但我不确定,因为它们无法更改。请帮忙。如果有帮助,我可以上传解释输出。
更多信息:如下所示,更改要转换的连接(cpp.PositionNumber,char(32))无效,因为时间可达10秒:
ON cem.entity_id = convert(cpp.PositionNumber, char(32)) and cem.entity_type = 'Security'
AND cem.scheme_id = 9901
没有转换的查询的解释输出在下面,并且尽可能看到PRIMARY(但不在带转换的查询中):
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE cpp index_merge Index1,FundId_idx,PeriodEndDate_idx FundId_idx,PeriodEndDate_idx 3,3 402 Using intersect(FundId_idx,PeriodEndDate_idx); Using where
1 SIMPLE cem ref PRIMARY,fk_classification_entity_map_1 fk_classification_entity_map_1 4 const 24100