2013-04-27 66 views
0

我有一个问题/答案表设置,以便当客户加载产品页面时,它会询问有关产品的问题。为了防止他们一遍又一遍地看到相同的问题,我有一个查询将答案表连接到问题表上,并选择该用户尚未为该产品回答的前3个问题。MySQL - 表JOIN不使用正确的INDEX

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中。有人可以向我解释为什么会发生这种情况吗?我只需要一个不同的索引?我试图改变答案现有的主键,一个唯一的密钥并添加

`id` int(10) unsigned NOT NULL AUTO_INCREMENT 

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

任何帮助,将不胜感激。

谢谢!

回答

0

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

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

+0

是的,这是正确的。我想回复前三个未解答的问题。我不希望客户回答同一产品的相同问题。问题是不是特定产品的通用问题。如果他们是问题表中的专栏,我将不得不重复所有40,000个产品的35个问题,而不是有35个问题,并且让用户回答问题和产品。 – Xengulai 2013-04-27 03:51:33