MySQL - table JOIN没有使用正确的INDEX



我设置了一个问题/答案表,以便当客户加载产品页面时,它会询问有关产品的问题。为了防止他们反复看到相同的问题,我有一个查询,它将答案表连接到问题表,并选择该用户尚未回答的前3个问题。

CREATE TABLE `questions` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `question` varchar(100) NOT NULL,
    PRIMARY KEY (`id`),
    UNIQUE KEY `idquestion` (`id`,`question`)
) ENGINE=InnoDB AUTO_INCREMENT=37 DEFAULT CHARSET=utf8

CREATE TABLE `answers` (
    `questionId` int(11) NOT NULL,
    `userId` int(11) NOT NULL,
    `productId` int(11) NOT NULL,
    `answer` tinyint(3) unsigned NOT NULL DEFAULT ''0'',
    PRIMARY KEY (`questionId`,`userId`,`productId`),
    KEY `questionId` (`questionId`),
    KEY `userId` (`userId`),
    KEY `productId` (`productId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

我使用的查询是:

SELECT q.`id`, q.`question`
FROM `questions` q
LEFT JOIN `answers` a
ON q.`id` = a.`questionId` AND a.`userId` = <userid> AND da.`productId` = <productid>
WHERE a.`productId` IS NULL
LIMIT 3;

这是EXPLAIN EXTENDED的结果:

1   SIMPLE  q   index       idquestion  306     34  100.00  Using index
1   SIMPLE  a   eq_ref  questionIduserIdproductId,questionId,userId,productId   questionIduserIdproductId   12  sandbox.q.id,const,const    1   100.00  Using where; Using index; Not exists

查询可以很好地返回尚未回答的适当问题。问题是这个查询在负载下会延迟,即使两行都显示它正在使用索引,当我启用log-queries-not-using-indexes时,这个查询仍然显示在slow-query.log中。有人能给我解释一下为什么会这样吗?我只需要一个不同的索引吗?我已经尝试将答案的现有PRIMARY键更改为唯一键并添加

`id` int(10) unsigned NOT NULL AUTO_INCREMENT

作为PRIMARY键,但是没有做任何事情。

如有任何帮助,不胜感激。

谢谢!

我很困惑,为什么productId不是问题表的一部分,而不是答案表的一部分。这个查询看起来会返回任何产品的前3个未回答的问题…

查询慢是因为LEFT JOIN。您将返回questions中没有answers中匹配行的每一行。这可以使用idquestion索引来完成(因为您想要的两列都在索引中),但是需要每次都探测answers表。

相关内容

  • 没有找到相关文章

最新更新