优化Mysql查询

时间:2009-10-28 17:05:57

标签: php sql mysql optimization

此类功能的一般“最佳做法”是什么。

我有一个用户表,一个民意调查表和一个网站上的民意调查表。我想加载一个加载用户尚未回答的民意调查的页面。

最有效和“最好”的方法是什么。

我尝试过的事情似乎很慢/不理想:

使用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查询)

4 个答案:

答案 0 :(得分:3)

只要您在responses (pollID, username)

上有复合索引,这两个查询的效率都相同

如果你的查询很慢,这很可能意味着你没有这个索引。

LEFT JOIN列上的

IS NULLNULL相结合,由MySQL优化,以便在看到没有匹配值时返回一行右栏。

您可以在EXPLAIN列中的Not exists Extra中看到它。

NOT IN的优化方式也相同,您可以在<not exists>提供的警告消息中将其视为EXPLAIN EXTENDED

有关详细信息,请参阅我的博客中的此条目:

答案 1 :(得分:0)

如果您在responsespollID上提供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'