2011-08-05 12 views
4

私は1で2つのテーブルがあります:1の関係を(それはおそらく1になる可能性:N将来の関係)を次のように私が行う必要がある結合テーブルのパフォーマンスの欄BY ORDER

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 

は、私は、単一の中に2つのテーブルをマージ横に最適化のためのクエリを何かできることはあります1(1:N関係の可能性を失う)?

私はテーブルarticleに列を追加し、それを更新するためにトリガーを使用することを考えていました。このようにして、私は両方の列にインデックスを追加することができ、順序はより速くなるはずです。

クエリを最適化する方法は他にありますか?

おかげ

+1

article_topにはどのようなインデックスがありますか? – gbn

+0

私は 'article_id'と' article_top_id'にインデックスを持っていますが、 'article_top'テーブルが空のときはクエリが遅いので、' until'にインデックスを追加すると助けになるかどうかわかりません。 –

+0

order byの両方の列は、おそらく索引付けされるべきです... article_top.untilの索引が欠落していると、パフォーマンスが低下する可能性がありますが、まず問合せ計画を見てください。 –

答えて

1

articleテーブルにtop_until列を追加し、その値が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

これは私が考えていた解決策です。多分それは最高です。唯一の質問:WHERE句でフィルタリング目的で使用されることがある、より多くのインデックス付きカラムが 'article'テーブルにあります。この事実(否定的)は、ソート中のコンポジットインデックスの使用に影響を与えますか?複合インデックスにいくつかの列を追加する必要がありますか? –

+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 –