SQL左连接查询运行非常慢

Bri*_*ian 9 mysql sql optimization

基本上我正在尝试提取一个用户尚未从数据库响应的随机轮询问题.这个查询大约需要10-20秒才能执行,这显然不行!响应表大约是30K行,数据库也有大约300个问题.

SELECT  questions.id
FROM  questions
LEFT JOIN  responses ON ( questions.id = responses.questionID
AND responses.username =  'someuser' ) 
WHERE
responses.username IS NULL 
ORDER BY RAND() ASC 
LIMIT 1
Run Code Online (Sandbox Code Playgroud)

问题和响应表的PK是"id",如果重要的话.

任何建议将不胜感激.

Cha*_*ion 11

你很可能需要一个索引

responses.questionID
responses.username 
Run Code Online (Sandbox Code Playgroud)

没有索引搜索30k行总是很慢.


nic*_*ckf 5

这是一种不同的查询方法,可能会更快:

SELECT q.id
FROM questions q
WHERE q.id NOT IN (
    SELECT r.questionID
    FROM responses r
    WHERE r.username = 'someuser'
)
Run Code Online (Sandbox Code Playgroud)

确保有一个索引r.username,这应该很快。

以上将返回所有未回答的问题。要随机选择一个,您可以选择低效(但容易)ORDER BY RAND() LIMIT 1的方法,或者使用 Tom Leys 建议的方法。

  • @ChaosPandion:LEFT JOIN/IS NULL 和 NOT IN **是最快(和等效)选项**:http://explainextended.com/2009/09/18/not-in-vs-not-exists-vs- left-join-is-null-mysql/ (2认同)
  • @Chaos:真的吗?我发现“NOT IN”更能描述您实际尝试做的事情。也许这只是我一个人,但我可以将 `NOT IN` 版本读成一句话“获取 'someuser' 没有回应的问题的 id”。我不能用 LEFT JOIN 做同样的事情。 (2认同)
  • @unknown:只有在 SELECT 子句**内**使用 SELECT 时才会出现这种情况。阅读链接,并注意我所说的关于 LEFT JOIN/IS NULL 是 **only** 对 MySQL 有效的内容...... (2认同)