Mysql 优化查询以使用主键而不是其他索引

Mysql 优化查询以使用主键而不是其他索引,mysql,sql,Mysql,Sql,我正在尝试优化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, `Marke

我正在尝试优化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中,由于查询使用的是fk_classification_entity_map_1索引,而不是classification_entity_map表上的主索引,因此查询所用的时间比预期的要长(9.4秒)。cpp有626648行,cem有63487行

我怀疑该问题与cem.entity_id&cpp.PositionNumber的数据类型有关,但我不确定,因为它们无法更改。请帮忙。如果有帮助,我可以上传解释输出

更多信息:将连接更改为convert(cpp.PositionNumber,char(32)),如下所示没有帮助,因为时间长达10秒:

ON cem.entity_id = convert(cpp.PositionNumber, char(32)) and cem.entity_type =   'Security'
AND cem.scheme_id = 9901
不带convert的查询的explain输出如下所示,并尽可能地看到主查询(但不在带convert的查询中):


解释总是有用的?我想知道MySQL优化器是否将主键表外分类\实体\映射视为一个可能的键。您的问题确实存在于您加入混合类型的ON子句中。。cem.entity\u id varchar(32)vs cpp.PositionNumber mediumint(9)你永远不能像这样加速它。。如果不使用Converter,您可以更改主键中列的顺序吗?如果您将其更改为
(entity\u type,scheme\u id,entity\u id)
,或者将
fk\u classification\u entity\u map\u 1
更改为
(scheme\u id,entity\u type)
,我认为这应该会有所帮助,因为这样您就可以在
ON
子句中测试的两列使用其中一个索引。有趣的是,Toad for MySQL将主键用于convert查询,但不用于普通查询。为什么客户机工具很重要?在连接中执行
convert()
不会有帮助。如果MySQL要利用索引,则需要两个列的类型相同。
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