我正在连接一个表,注意到如果我连接的字段的varchar大小太大,那么MySQL就不会在连接中使用该字段的索引,从而导致查询时间明显延长。我在下面给出了解释和表定义。它是MySQL 5.7版本。知道为什么会发生这种情况吗?
表格定义:
CREATE TABLE `LotRecordsRaw` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`lotNumber` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`scrapingJobId` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `lotNumber_UNIQUE` (`lotNumber`),
KEY `idx_Lot_lotNumber` (`lotNumber`)
) ENGINE=InnoDB AUTO_INCREMENT=14551 DEFAULT CHARSET=latin1;
解释道:
explain
(
select lotRecord.*
from LotRecordsRaw lotRecord
left join (
select lotNumber, max(scrapingJobId) as id
from LotRecordsRaw
group by lotNumber
) latestJob on latestJob.lotNumber = lotRecord.lotNumber
)
产生:
上面的屏幕截图显示了派生表没有使用“lotNumber”上的索引。在那个例子中,“lotNumber”字段是一个varchar(255)。如果我将其更改为一个较小的大小,例如varchar(45),那么解释查询将产生如下结果:
然后,查询的运行速度提高了几个数量级(2秒而不是100秒)。
1条答案
按热度按时间t3irkdon1#
万岁!你找到了一个优化的理由,不用盲目地在
VARCHAR
中使用255。请试试191和192,我想知道这是不是分界线.
同时,我还有一些其他的意见:
UNIQUE
是KEY
。也就是说,idx_Lot_lotNumber
是冗余的,也可以删除。INDEX(lotNumber, scrapingJobId)
作为查找这些MAX的更快方法。lotNumber
是唯一的,因此每个lotNumber只有一行。这意味着MAX
和GROUP BY
完全没有必要!lotNumber
可以升级为PRIMARY KEY
(并完全摆脱id
)。