2014-02-25 41 views
0

我有兩個表,posts和posts_relationship。避免查詢中的文件夾

posts:id, title, text, lang, timestamp 

posts_relationship: id, post_id, subcategory_id 

這是我的查詢:

SELECT posts.title, 
     posts.timestamp 
    FROM posts_relationship 
    INNER JOIN posts ON posts.id = posts_relationship.post_id 
    WHERE posts.lang = 'it' AND 
     posts.timestamp <= NOW() AND 
     posts_relationship.subcategory_id = 21 
    ORDER BY posts.timestamp DESC 

我已經posts.langposts.timestampposts_relationships.post_idposts_relationship.subcategory_id添加索引。

但與解釋我總是臨時或Filesort。

我怎樣才能只有「使用哪裏」?

+0

一個'posts.id'將有所幫助。取決於大小,mysql可能會選擇不使用索引來替換較小的結果集 – exussum

+0

用靜態日期替換您的<= NOW()'(從應用程序派生,作爲示例),並通過'(timestamp,lang)'創建索引表'職位'。請注意,MySQL永遠不能使用多個索引,因此,'(timestamp,lang)'索引將適合'WHERE'和'ORDER BY'子句,但不會使用'subcategory_id'索引。所以它不是100%保證你會避免文件。文件也可能意味着它實際上是在_memory_中排序(這要快得多) –

+0

文件排序是針對'order by'而不是'where'。 –

回答

0

這是我不清楚這行做:

posts.timestamp <= NOW() AND 

你如何獲得的時間戳是在未來?

沒有這一行,那麼這個查詢看起來像:

SELECT p.title, p.timestamp 
FROM posts_relationship pr INNER JOIN 
     posts p 
     ON p.id = pr.post_id 
WHERE p.lang = 'it' AND 
     pr.subcategory_id = 21 
ORDER BY p.timestamp DESC; 

與此查詢,在posts(lang, timestamp, id)指數可能會阻止文件排序。查詢以下版本可能會保證這一點更是:

SELECT p.title, p.timestamp 
FROM posts p 
WHERE p.lang = 'it' AND 
     exists (select 1 
       from posts_relationship pr 
       where p.id = pr.post_id and pr.subcategory_id = 21 
      ) 
ORDER BY p.timestamp DESC; 

我不認爲這個查詢將使用文件分類有以下兩個指標:

posts(lang, id, timestamp) 
posts_relationship(post_id, subcategory_id) 

(順便說一句,你可以保持時間戳的條件,我只是不明白爲什麼它是必要的。)

+0

我嘗試使用您的第一個查詢,但Filesort始終存在。未來的時間戳用於隱藏未來的帖子,當我想在特定時間發佈帖子時。 – virtusroma

+0

@virtusroma。 。 。最後一個查詢是否消除了文件排序而沒有'timestamp'上的附加條件? –

+0

第二個查詢產品無限「發送數據」...我有100.000個帖子:) – virtusroma