我有一个问题/答案表设置,以便当客户加载产品页面时,它会询问有关产品的问题。为了防止他们反复看到相同的问题,我有一个查询将答案表连接到问题表上,并选择该用户尚未为该产品回答的前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键以获得UNIQUE键的答案并添加
`id` int(10) unsigned NOT NULL AUTO_INCREMENT
作为PRIMARY键,但没有做任何事情。
任何帮助都将不胜感激。
谢谢!
答案 0 :(得分:0)
我很困惑为什么productId不是问题表的一部分,而不是答案表。此查询看起来会返回任何产品的前三个未回答的问题......
慢查询是因为LEFT JOIN。您将返回questions
中没有匹配行的answers
的每一行。这可以使用idquestion索引来完成(因为您想要的两列都在索引中),但每次都需要探测答案表。