MySQL不在内连接上使用主键

时间:2018-04-09 20:47:51

标签: mysql join primary-key

我有两张桌子: 表1:

CREATE TABLE `lk_transaction_types` (
  `transactionTypeID` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `isActive` tinyint(2) unsigned NOT NULL,
  `code` varchar(8) NOT NULL,
  `description` varchar(150) NOT NULL,
  `isInbound` tinyint(2) unsigned NOT NULL DEFAULT '1',
  `isOutbound` tinyint(2) unsigned NOT NULL DEFAULT '1',
  PRIMARY KEY (`transactionTypeID`)
) ENGINE=InnoDB AUTO_INCREMENT=32 DEFAULT CHARSET=utf8;

表2:

CREATE TABLE `ediLoad` (
  `loadID` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `processID` int(10) unsigned NOT NULL,
  `success` tinyint(2) unsigned NOT NULL DEFAULT '0',
  `transactionTypeID` tinyint(2) unsigned DEFAULT NULL,
  `escoID` int(10) unsigned DEFAULT NULL,
  `ldcID` int(10) unsigned DEFAULT NULL,
  `commodityType` tinyint(3) unsigned NOT NULL DEFAULT '0',
  `filename` varchar(150) NOT NULL,
  `loadDate` datetime NOT NULL,
  `processed` tinyint(2) unsigned NOT NULL DEFAULT '0',
  `processedDate` datetime DEFAULT NULL,
  `dataApplied` tinyint(2) unsigned NOT NULL DEFAULT '0',
  `dataAppliedDate` datetime DEFAULT NULL,
  `errorID` tinyint(3) unsigned DEFAULT NULL,
  `error` tinyint(2) unsigned DEFAULT '0',
  `warning` tinyint(2) unsigned DEFAULT '0',
  PRIMARY KEY (`loadID`),
  KEY `idx_processID` (`processID`,`transactionTypeID`,`escoID`),
  KEY `idx_escoID` (`escoID`),
  KEY `idx_filename` (`success`,`filename`),
  KEY `idx_bulk` (`processed`,`loadDate`),
  KEY `idx_loadDate` (`loadDate`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=35086005 DEFAULT CHARSET=utf8;

尝试运行简单查询时,它不使用lk_transaction_types表上的主键:

SELECT COUNT(0)
FROM edi.ediLoad l
INNER JOIN edi.lk_transaction_types lk 
  ON  lk.transactionTypeID = l.transactionTypeID
WHERE l.escoID = 2
AND lk.isActive = 1
AND lk.isInbound = 1;

查询非常慢。所以我运行解释

EXPLAIN SELECT COUNT(0)
FROM edi.ediLoad l
INNER JOIN edi.lk_transaction_types lk 
  ON  lk.transactionTypeID = l.transactionTypeID
WHERE l.escoID = 2
AND lk.isActive = 1
AND lk.isInbound = 1;

返回

id  select_type table   partitions  type    possible_keys   key key_len ref rows    filtered    Extra
1   SIMPLE  lk  NULL    ALL PRIMARY NULL    NULL    NULL    31  3.23    Using where
1   SIMPLE  l   NULL    ref idx_escoID  idx_escoID  5   const   71580   10.00   Using where

这似乎是一个简单的查询,主键上有一个连接。为什么不使用主键?我甚至尝试在连接中添加'FORCE INDEX FOR JOIN(PRIMARY)',它仍然不使用主键。任何帮助都会很棒。谢谢!

1 个答案:

答案 0 :(得分:0)

详细说明@Uueerdo在上述评论中所说的内容:在这种情况下,MySQL无法使用 idx_processID 索引,因为 transactionTypeID 是第二个索引中的列,第一个列( processID )不是where语句的一部分。

如果仅使用 transactionTypeID 添加新密钥,则会使用该密钥。

来自https://dev.mysql.com/doc/refman/5.7/en/multiple-column-indexes.html

  

MySQL可以对测试所有内容的查询使用多列索引   索引中的列,或仅测试第一列的查询,   前两列,前三列,依此类推。如果你指定   索引定义中的列顺序正确,单个   复合索引可以加快几种查询的速度   表