2011-08-05 67 views
4

專欄中,我有1 2個表:1間的關係(但它可能會成爲一個1:N的未來關係)如下:ORDER BY的連接表性能

CREATE TABLE article (
    article_id INT, 
    inserted DATETIME 
) ENGINE InnoDB; 

CREATE TABLE article_top (
    article_top_id INT, 
    article_id INT, 
    until DATETIME 
) ENGINE InnoDB; 

我需要做的是選擇首先按article_top.until DESC排序並按article.inserted DESC排序的文章(因此「頂部」文章在頂部,其餘部分按最新到最舊排序)。

我下面的查詢,這是緩慢的(快,當我跳過了ORDER BY子句article_top.until):

SELECT * FROM article 
LEFT JOIN article_top 
ON article.article_id = article_top.article_id 
ORDER BY article_top.until DESC, article.inserted DESC 
LIMIT 20 

有什麼我可以爲優化做兩個表合併爲單一旁邊的查詢一個(失去1:N關係的可能性)?

我在考慮在表article中增加額外的列並使用觸發器來更新它。這樣我可以將索引添加到兩列,並且排序應該更快。

是否有任何其他方式如何優化查詢?

感謝

+1

您現在在article_top上有哪些索引? – gbn

+0

我在'article_id'和'article_top_id'上有索引...但是當'article_top'表爲空時,查詢很慢,所以我不確定是否將索引添加到'until'會有幫助。 –

+0

這兩個列的順序可能應該被編入索引... article_top.until上缺少的索引可能是性能較差的原因,但首先查看查詢計劃。 –

回答

1

添加top_until列到article表有它的價值,從article_top表中複製(在插入​​時或使用手動觸發),並給不在article_top表零「top_until」貴重物品。然後對top_untilinserted列的多列索引:

INDEX(top_until, inserted) 

和查詢這樣的:

SELECT * FROM article 
    ORDER BY top_until DESC, inserted DESC 
    LIMIT 20 

這應該立即給出結果。

+0

這是我在考慮的解決方案。也許這是最好的。只有一個問題:'article'表中有更多的索引列,有時在WHERE子句中用於過濾目的。這個事實(消極地)影響排序時使用複合索引嗎?我應該將一些列添加到組合索引中嗎? –

+0

@PetrPeller如果希望MySql在對列進行排序時使用索引,它們必須以與它們在索引中出現的順序相同的順序出現在ORDER BY子句中,也不應混合使用ASC和DESC。你可以在索引末尾添加額外的列,但不是開頭,'INDEX(top_until,inserted,other_column)'將會工作,但是'INDEX(other_column,top_until,inserted)'不會。 – nobody

+0

我知道這一點,但mysql文檔指出,在以下情況下不使用索引:「用於提取行的鍵不同於在ORDER BY中使用的鍵」。 http://dev.mysql.com/doc/refman/5.6/en/order-by-optimization。html –