此类功能的一般“最佳做法”是什么。
我有一个用户表,一个民意调查表和一个网站上的民意调查表。我想加载一个加载用户尚未回答的民意调查的页面。
最有效和“最好”的方法是什么。
我尝试过的事情似乎很慢/不理想:
使用NOT IN
进行嵌套选择的查询SELECT p.id
FROM poll p
WHERE p.id NOT IN (
SELECT r.pollID
FROM responses r
WHERE r.username = 'someuser'
)
使用左连接的查询
LEFT JOIN responses ON ( polls.id = responses.pollID
AND responses.username = 'someuser' )
WHERE
responses.username IS NULL
这两种解决方案似乎规模都很差。
其他建议?打开盒子外的任何东西。 (I.E.解决方案不仅限于不同类型的mysql查询)
答案 0 :(得分:3)
只要您在responses (pollID, username)
如果你的查询很慢,这很可能意味着你没有这个索引。
非LEFT JOIN
列上的 IS NULL
与NULL
相结合,由MySQL
优化,以便在看到没有匹配值时返回一行右栏。
您可以在EXPLAIN
列中的Not exists
Extra
中看到它。
NOT IN
的优化方式也相同,您可以在<not exists>
提供的警告消息中将其视为EXPLAIN EXTENDED
。
有关详细信息,请参阅我的博客中的此条目:
答案 1 :(得分:0)
如果您在responses
和pollID
上提供username
复合密钥,则左连接应该会很有效。
虽然使用用户名作为密钥而不是数字用户ID有点令人沮丧。
答案 2 :(得分:0)
解决方案#1:
直接向左连接如何为您执行?
LEFT JOIN responses ON ( polls.id = responses.pollID
AND responses.username = 'someuser' )
如果执行正常,您只需检索完整的民意调查列表,然后过滤掉调用者代码中username不为空的行。
解决方案#2:
确保你的指数没问题。您应该在响应中使用用户名(或投票ID +用户名)中的ann索引。
答案 3 :(得分:-1)
我认为Left Join将是您最好的选择。但是,我很困惑为什么在你的例子中你检查用户名,然后在where子句中,看看它是否为null。它应该是这样的:
LEFT JOIN responses ON ( polls.id = responses.pollID)
WHERE
responses.username = 'someuser'