MySQL:如何简化“IN”查询
我知道我必须避免使用“IN”子句,但在这种情况下我不知道该怎么办。该方案是这样的:从PHP我得到值的列表,然后我建立这样的查询:MySQL:如何简化“IN”查询
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
这使得我的网站很慢(因为它每次执行一个用户访问它)。如何使它更快?
我相信你可以简化查询:
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
也可以给你买一些额外的服务表现。尝试每个和比较。
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
我测试过,第一个是最快的。谢谢 – Ivan 2011-06-02 20:25:23
摆脱子选。 IN()
子句完全正确。
继AJ的要求写下来更正查询:
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
上面的代码没有进行测试,并可能包含一些严重的错误(写入临时) - 如果你发现任何,请给我反馈评论。
加
不要忘了添加适当的索引。
如果您重新编写查询以显示OP如何改进,将会很有帮助。 – 2011-06-02 19:04:26
@AJ我已经根据您的请求写下了我的建议版本,但它可能包含许多错误,例如从错误的表中获取列。 – Tadeck 2011-06-02 19:19:15
我注意到,IN是一系列连续的值
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 and an extra number 20.
的你可以只用
WHERE (r.id = 20) OR (r.id BETWEEN 2 AND 18)
快得多更换这里,因为你只需要做3比较最坏的情况。
如果你有随机值
使用临时存储器表。
使用散列主键。
并对主散列键进行内连接。
时间这个,告诉我它快多了:-)
谢谢,但值可以随机:) – Ivan 2011-06-02 20:24:59
为什么不把'IN'移到子选择? – Halcyon 2011-06-02 19:00:31