[英]Optimize query: Select in Select
Lets say i have a table to store the blogs (table name is blogs) of each user. 假设我有一个表来存储每个用户的博客(表名是博客)。 But also have a table to store the blogs from other users that the user liked (table name is likedBlogs), yes?
但是还有一个表来存储用户喜欢的其他用户的博客(表名是likesBlogs),是吗?
so to retrieve them i just do: -Select user's blogs. 所以要检索它们我只是这样做: - 选择用户的博客。 -Add the blogs he liked.
- 添加他喜欢的博客。
$q = mysql_query("
SELECT id
FROM blogs
WHERE (iduser = $id)
OR id IN
(SELECT idblog
FROM likedBlogs
WHERE iduser='$id')
AND (id > 0)
ORDER BY id DESC
LIMIT 20
") or die(mysql_error());
Can i do this better? 我能做得更好吗? (how would you qualify in performance this query?)
(你如何在这个查询中获得性能?)
Thanks 谢谢
I believe you can better refactor it usign EXISTS instead of IN. 我相信你可以更好地重构它使用EXISTS而不是IN。
IN
requires the entire result set be returned and then begin search for a value, but EXISTS
check row by row and interrupt inner query when first occurence is found. IN
要求返回整个结果集,然后开始搜索值,但EXISTS
逐行检查并在第一次出现时中断内部查询。
SELECT id
FROM blogs
WHERE (iduser = $id)
OR EXISTS
(SELECT idblog
FROM likedBlogs
WHERE iduser='$id' AND idblog = id)
AND (id > 0)
ORDER BY id
DESC LIMIT 20
See Optimizing IN/=ANY Subqueries 请参阅优化IN / = ANY子查询
very useful optimization is to “inform” the subquery that the only rows of interest are those where the inner expression inner_expr is equal to outer_expr.
非常有用的优化是“通知”子查询,唯一感兴趣的行是内部表达式inner_expr等于outer_expr的行。 This is done by pushing down an appropriate equality into the subquery's WHERE clause.
这是通过将适当的相等性下推到子查询的WHERE子句中来完成的。 That is, the comparison is converted to this: EXISTS (SELECT 1 FROM ... WHERE subquery_where AND outer_expr=inner_expr)
也就是说,比较转换为:EXISTS(SELECT 1 FROM ... WHERE subquery_where AND outer_expr = inner_expr)
Usually you would use join
instead of nested select
's. 通常你会使用
join
而不是嵌套的select
。
select blogs.id
from blogs inner join likedBlogs on (blogs.iduser = likedBlogs.iduser and blogs.id = likedBlogs.idblog)
where blogs.iduser = $id
and blogs.id > 0
order by blogs.id desc limit 20
upd first time I didn't read task statement correctly upd第一次我没有正确读取任务语句
select blogs.id
from blogs left join likedBlogs on (blogs.id = likedBlogs.idblog)
where blogs.iduser = $id or likedBlogs.iduser = $id;
Your query looks fine to me. 您的查询对我来说很好。 For performance you should make sure you have indexes on the id columns in your database tables.
为了提高性能,您应该确保在数据库表的id列上有索引。
I think you might be better served by a union 我认为工会可能会更好
SELECT id
FROM blogs
WHERE iduser = $id AND id > 0
UNION
SELECT idblog AS id
FROM likedBlogs
WHERE iduser='$id' AND idblog > 0
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.