首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >MySQL:如何简化"IN“查询

MySQL:如何简化"IN“查询
EN

Stack Overflow用户
提问于 2011-06-03 02:56:19
回答 3查看 92关注 0票数 2

我知道我必须避免使用" in“子句,但我不知道在这种情况下该怎么做。场景是这样的:我从PHP获得一个值列表,然后构造一个查询,如下所示:

代码语言:javascript
复制
SELECT id FROM
    ( SELECT * FROM `tips` r 
      LEFT JOIN (SELECT tip FROM `tips_showed` WHERE user='8') AS a ON r.id=a.tip
      WHERE a.tip IS NULL ) AS t
WHERE t.id IN
    ('3','4','5','2','6','7','8','9','10','18',
     '11','12','13','14','15','16','17','20') LIMIT 1

这使得我的站点非常慢(因为每次用户访问它时都会执行它)。怎样才能让它更快呢?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-06-03 03:04:10

我相信您可以将查询简化为:

代码语言:javascript
复制
SELECT t.id
    FROM `tips` t
        LEFT JOIN `tips_showed` a
            ON t.id = a.tip
                AND a.user = '8'
    WHERE a.tip IS NULL
        AND t.id IN ('3','4','5','2','6','7','8','9','10','18',
                     '11','12','13','14','15','16','17','20')
    LIMIT 1

使用NOT EXISTS而不是LEFT JOIN可能还会为您带来一些额外的性能。尝试每种方法并进行比较。

代码语言:javascript
复制
 SELECT t.id
     FROM `tips` t
     WHERE t.id IN ('3','4','5','2','6','7','8','9','10','18',
                    '11','12','13','14','15','16','17','20')
        AND NOT EXISTS(SELECT NULL 
                           FROM `tips_showed` a 
                           WHERE a.tip = t.id
                               AND a.user = '8')
    LIMIT 1
票数 4
EN

Stack Overflow用户

发布于 2011-06-03 02:58:57

去除子选择IN()子句完全没问题。

在AJ要求写下更正后的查询后:

代码语言:javascript
复制
SELECT `r`.`id`
FROM `tips` AS `r`
LEFT JOIN `tips_showed` AS `a`
ON (`a`.`user`='8' AND `r`.`id`=`a`.`tip`)
WHERE `r`.`id` IN ('3','4','5','2','6','7','8','9','10','18',
     '11','12','13','14','15','16','17','20')
AND `a`.`tip` IS NULL
LIMIT 1

上面的代码没有经过测试,可能包含一些严重的错误(临时编写)-如果您发现任何错误,请在评论中给我反馈。

加号

不要忘记添加适当的索引。

票数 1
EN

Stack Overflow用户

发布于 2011-06-03 03:49:49

我注意到IN是值的连续序列

代码语言:javascript
复制
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 and an extra number 20.

您可以将此处的IN替换为

代码语言:javascript
复制
WHERE (r.id = 20) OR (r.id BETWEEN 2 AND 18)

更快,因为你只需要做3次最坏的比较。

如果有随机值,则为

使用临时内存表。

使用散列主键。

并在主散列键上执行内部联接。

计时并告诉我它有多快:-)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6219032

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档