2014-02-18 77 views
0

我有以下MySQL查詢如何提高此MySQL INNER JOIN的性能?

SELECT p. * 
FROM posts AS p 
INNER JOIN followings AS f ON p.id_user = f.id_user 
WHERE 
f.id_me =(my id) 
ORDER BY id LIMIT 11 

我有一個指標:在posts

  • followingsid_user, id_me

    • id_user

    followings表中的100K行,posts表中的30K行。

    我的問題是需要超過1秒,是否可以寫這個查詢,需要幾毫秒?

  • +0

    運行'EXPLAIN'併發布。 –

    +1

    經驗法則:任何在'join'或'where'中使用的字段,有時甚至是'order by'都應該有一個索引。但除此之外,查詢中很少有可以在查詢級別進行優化的 - 可以根據需要添加索引,也可以獲得更快的數據庫服務器。 –

    +0

    哪個表是按「ID」關聯的順序。您應該習慣使用table.column ...或alias.column進行查詢,因爲其他人試圖幫助您知道表格來源的正確上下文。 – DRapp

    回答

    0
    SELECT p. * 
    FROM posts AS p 
    INNER JOIN (SELECT id_me, id_user from followings order by id_me, id_user) AS f ON p.id_user = f.id_user 
    WHERE 
    f.id_me =(my id) 
    ORDER BY id LIMIT 11 
    

    通過創建一個sub_query,您可以在不改變表格的情況下在索引上添加索引。這應該會加快時間。如果這不工作,它是使用不當的索引這個查詢,你可以使用force_index ...但是這應有助於有點...

    +0

    這會更快嗎?現在你正在運行兩個查詢而不是一個查詢。 –

    +0

    ,因爲它限制了他從第二張桌子拉出的列,還有他沒有從選擇中拉取任何信息的表... – Hituptony

    +0

    它在加入 – Hituptony

    0

    試試這個:

    select p. * 
        from posts p 
        where p.id_user in 
        (select f.id_user 
         from 
        followings f 
        where 
        f.id_me =(my id)) 
        order by id limit 11 
    

    現在你是不是做兩個表之間的交叉產品,然後過濾它......現在你首​​先過濾大表(下面),因此它必須比聯接更快。

    -2

    如果添加索引是一個選項,請爲id(無論哪個表來自)添加一個索引,因爲它用於ORDER。請參閱http://www.mysqlperformanceblog.com/2006/09/01/order-by-limit-performance-optimization/ 通過向ORDER子句添加索引,我對大表的查詢從30秒降至3秒。

    也建議使ORDER列來自主表。因此,如果id來自posts表,那麼它已經是正確的,但如果不是,則反轉查詢中的表,選擇FROM followingsJOIN posts

    最後,如果id_user, id_me是一個多列索引,將其更改爲兩個單獨索引可能會有用,因爲它沒有利用WHERE子句中的索引。作爲多列索引,假設您正在尋找的id很少見,它仍然需要掃描大部分表格以找到您請求的limit。 正如其他人所提到的,將多列索引順序顛倒爲id_me,id_user將有所幫助,因爲WHERE子句將結果縮小到最快(同時假設您正在尋找的id很少見),但我不知道它是否仍然可以利用id_user部分進行連接,儘管這會產生較小的影響。

    +0

    這不會有幫助,因爲它不會幫助MySql快速獲取數據。與需要篩選以找到正確數據進行分類的數據量相比,需要排序的數據量可以忽略不計。 –

    0

    你的查詢沒有什麼根本性的錯誤,你的索引也不遠。

    爲了獲得最大的索引,瞭解不只是列將要使用很重要,但最有效的順序,他們應該被使用以便讓您的數據出來。

    將您的索引替換爲following,其中一個爲id_me, id_user(與您所描述的相反)。

    這樣,MySQL能夠:

    • 查找following第一右行通過在索引的一小片仰視(即減少它需要做的工作量的最好方式)
    • 使用following索引中的id_user數據以...
    • 使用該表上的現有索引在posts中找到正確的行。

    基本上試圖找出你如何會找到的數據,然後提供索引,以幫助MySQL的爲你做它。

    +0

    我不是在子查詢中這樣做嗎? – Hituptony

    +0

    是的 - 你正在問MySql這樣做,我正在幫你創建索引,這意味着MySql能夠及時地完成它(按照你的問題)。 I.E.您的查詢沒有任何根本性錯誤。 –

    +0

    謝謝羅布。好的解釋 – Hituptony