2011-10-26 178 views
1

可以說,我有一個表來存儲每個用戶的博客(表名是博客)。 但也有一個表來存儲用戶喜歡的其他用戶的博客(表名是likedBlogs),是嗎?優化查詢:選擇在選擇

所以檢索他們我只是這樣做: - 選擇用戶的博客。 - 添加他喜歡的博客。

$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()); 

我可以做得更好嗎? (你將如何在性能上符合此查詢?)

感謝

回答

2

我相信你可以更好地重構它usign EXISTS代替。

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 

Optimizing IN/=ANY Subqueries

非常有用的優化是「通知」的子查詢的唯一 行的利益是那些內表達inner_expr是 等於outer_expr。這是通過向子查詢的WHERE子句中按下適當的 等式來完成的。也就是說,比較 轉換成這樣:EXISTS(SELECT 1 FROM ... WHERE subquery_where和 outer_expr = inner_expr)

+0

是EXISTS更快得到更好的服務? –

+1

@Toni Michel Caubet:是的,在大數據集上很明顯。請參閱我提供的鏈接,我相信你可以在intrawebs中搜索'EXISTS vs IN MySql',你會發現很多評論 – sll

+1

在SQL Server 2005+中,'EXISTS'和'IN'評估相同,謝天謝地。 – JNK

0

您的查詢看起來好像沒什麼問題。爲了提高性能,您應該確保在數據庫表中的id列上有索引。

+0

uf,我還沒有使用索引呢......我還沒有發現任何易於理解的東西.. –

2

通常你會使用join而不是嵌套select's。

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第一次我沒看過的任務說法正確

select blogs.id 
from blogs left join likedBlogs on (blogs.id = likedBlogs.idblog) 
where blogs.iduser = $id or likedBlogs.iduser = $id; 
+0

謝謝,比http://stackoverflow.com/questions/7902611/optimize-query-select-in-select更快/ 7902656#7902656? –

+0

INNER JOIN對於沒有在likedBlogs中輸入的情況有效嗎? – sll

+0

我想知道:) –

0

我想你可能由工會

SELECT id 
FROM blogs 
WHERE iduser = $id AND id > 0 
UNION 
SELECT idblog AS id 
FROM likedBlogs 
WHERE iduser='$id' AND idblog > 0