2013-06-04 82 views
0

這裏有一個查詢:爲什麼一個查詢比另一個查詢更快?

SELECT DISTINCT 
    spentits.*, 
    username, 
    (SELECT count(*) from likes where likes.spentit_id = spentits.id) as like_count, 
    (SELECT count(*) from comments where comments.spentit_id = spentits.id) as comment_count, 
    (SELECT count(*) from wishlist_items where wishlist_items.spentit_id = spentits.id) as wishlist_count, 
    (case when likes.id is null then 0 else 1 end) as is_liked_by_me, 
    (case when wishlist_items.id is null then 0 else 1 end) as is_wishlisted_by_me 
FROM spentits 
LEFT JOIN users ON users.id = spentits.user_id 
LEFT JOIN likes ON likes.user_id = 9 AND likes.spentit_id = spentits.id 
LEFT JOIN wishlist_items ON wishlist_items.user_id = 9 AND wishlist_items.spentit_id = spentits.id 
WHERE spentits.user_id IN 
    (SELECT follows.following_id 
    FROM follows 
    WHERE follows.follower_id = 9) 
ORDER BY id DESC 
LIMIT 15; 

這需要平均43ms執行。現在另一個沒有where子句的查詢(下面),更不用說第二個SELECT子查詢,執行速度慢了5倍(240ms)!

SELECT DISTINCT 
    spentits.*, 
    username, 
    (SELECT count(*) from likes where likes.spentit_id = spentits.id) as like_count, 
    (SELECT count(*) from comments where comments.spentit_id = spentits.id) as comment_count, 
    (SELECT count(*) from wishlist_items where wishlist_items.spentit_id = spentits.id) as wishlist_count, 
    (case when likes.id is null then 0 else 1 end) as is_liked_by_me, 
    (case when wishlist_items.id is null then 0 else 1 end) as is_wishlisted_by_me 
FROM spentits 
LEFT JOIN users ON users.id = spentits.user_id 
LEFT JOIN likes ON likes.user_id = 9 AND likes.spentit_id = spentits.id 
LEFT JOIN wishlist_items ON wishlist_items.user_id = 9 AND wishlist_items.spentit_id = spentits.id 
ORDER BY id DESC 
LIMIT 15; 

爲什麼?不應該第二個查詢快得多,因爲沒有條件,沒有第二個查詢。所有數據庫需要做的是選擇最後15條記錄,與第一條記錄進行比較,在第一條記錄執行子查詢之後掃描每條記錄並檢查其中是否包含id。我真的很困惑,應該執行得更快的查詢實際上慢了5倍。

+0

有一些與統計和元數據相關的執行路徑,爲兩者執行「解釋計劃」。如果您不通過該篩選器篩選行進行篩選,則通過id篩選可能會在沒有行的表上執行跳過操作。 – ssedano

+0

是不是因爲第一個有where子句會帶回更少的行? – anna

+0

@anna他們都有限制15 – 0xSina

回答

1

有一些執行路徑與統計數據和元數據相關,爲兩者執行explain plan並查看執行路徑。

此外,如果您沒有按照該ID篩選行進行投影,則通過ID篩選可能會在沒有匹配行的表上執行跳過操作。

相關問題