2011-06-17 10 views
1

私はメインサイトに表示するためのFeaturedContentを見つけるニュースサイトのクエリに取り組んでいます。この方法でマークされたコンテンツは、「FeaturedContent」としてタグ付けされ、「ホームページ」によって特集された表で注文されます。私は現在、必要な出力を持っていますが、クエリは3秒以上で実行されます。これを減らす必要があります。次のようなクエリを最適化するにはどうすればよいですか?MYSQLトリプルジョインパフォーマンスヘルプ、Tmpテーブルへのコピー

EDITは:提案として0.4秒まで、ビューごとに分をマテリアライズド:

SELECT f.position, s.item_id, s.item_type, s.title, s.caption, s.date 
FROM live.search_all s 
INNER JOIN live.tags t 
ON s.item_id = t.item_id AND s.item_type = t.item_type AND t.tag = 'FeaturedContent' 
LEFT OUTER JOIN live.featured f 
ON s.item_id = f.item_id AND s.item_type = f.item_type AND f.feature_type = 'homepage' 
ORDER BY position IS NULL, position ASC, date 

これは、日付順、他の機能の内容が続くために、すべてのホームページの機能を、返します。
このような説明になります。次のように

|-id---|-select_type-|-table-|-type---|-possible_keys---------|-key--------|-key_len-|-ref---------------------------------------|-rows--|-Extra-------------------------------------------------------------| 
|-1----|-SIMPLE------|-t2----|-ref----|-PRIMARY,tag_index-----|-tag_index--|-303-----|-const-------------------------------------|-2-----|-Using where; Using index; Using temporary; Using filesort;--------| 
|-1----|-SIMPLE------|-t-----|-ref----|-PRIMARY---------------|-PRIMARY----|-4-------|-newswires.t2.id---------------------------|-1974--|-Using index-------------------------------------------------------| 
|-1----|-SIMPLE------|-s-----|-eq_ref-|-PRIMARY, search_index-|-PRIMARY----|-124-----|-newswires.t.item_id,newswires.t.item_type-|-1-----|-------------------------------------------------------------------| 
|-1----|-SIMPLE------|-f-----|-index--|-NULL------------------|-PRIMARY----|-190-----|-NULL--------------------------------------|-13----|-Using index-------------------------------------------------------| 

とプロファイルは、次のとおりです。

|-Status---------------|-Time-----| 
|-starting-------------|-0.000091-| 
|-Opening tables-------|-0.000756-| 
|-System lock----------|-0.000005-| 
|-Table lock-----------|-0.000008-| 
|-init-----------------|-0.000004-| 
|-checking permissions-|-0.000001-| 
|-checking permissions-|-0.000001-| 
|-checking permissions-|-0.000043-| 
|-optimizing-----------|-0.000019-| 
|-statistics-----------|-0.000127-| 
|-preparing------------|-0.000023-| 
|-Creating tmp table---|-0.001802-| 
|-executing------------|-0.000001-| 
|-Copying to tmp table-|-0.311445-| 
|-Sorting result-------|-0.014819-| 
|-Sending data---------|-0.000227-| 
|-end------------------|-0.000002-| 
|-removing tmp table---|-0.002010-| 
|-end------------------|-0.000005-| 
|-query end------------|-0.000001-| 
|-freeing items--------|-0.000296-| 
|-logging slow query---|-0.000001-| 
|-cleaning up----------|-0.000007-| 

私はEXPLAIN出力を読み込むに新しいので、私はより良い秩序を持っている場合、私はわかりませんよ利用可能なもの、またはこれを高速化するために行うことができる簡単なもの。

search_all表は、定期的に更新されるマテリアライズド・ビュー表です。タグおよびフィーチャー表はビューです。これらのビューはオプションではなく、回避することはできません。

タグビューは、タグとリレーショナルテーブルを結合してitem_typeとitem_idに従ってタグのリストを取得しますが、他のビューはすべて1つのテーブルの単純なビューです。

編集:マテリアライズド・ビューでは、最大のボトルネックは「一時表へのコピー」手順のようです。出力を注文することなく、0.0025秒(はるかに良い!)の最終出力が必要です。そのステップのパフォーマンスを向上させる方法はありますか?

申し訳ありませんフォーマットを読みにくい場合は、私は新しく、定期的にどのように行われているのかわかりません。
ご協力いただきありがとうございます。何かが必要な場合は、私に教えてください!

EDIT:参照表のサイズ、:
タグの関係:197411個の
タグ:16897の
ストーリー:51801枚の
画像:28383本の
ビデオ:特集2408
:私が思う13

答えて

1

クエリを単独で最適化することはあまり役に立ちません。最初に、UNIONで作成されたサブクエリ自体を結合することは、単独ではパフォーマンス上の2つのボトルネックになっています。あなたは、データベースの構造を変更するオプションを持っている場合、彼らはしている場合、それは、のように非常に似ているよう

、そして私は、storiesimagesvideos 1に3つのテーブルをマージすることをお勧めし(それらをtype ENUM('story', 'image', 'video')を追加)レコードを区別する。サブクエリと共用体の両方が削除されます。

また、storiesvideosのあなたのビューは、コンテンツをフィルタリングするためにインデックスフィールドを使用していないようです。インデックス付きの列をクエリしていますか?

テーブルの構造全体とデータの再分割を知らなくても、かなり難しい問題です。

既存のデータベースに変更を加えることを含まない別のオプション(特に、すでに稼動中の場合)は、この情報をcronジョブによって定期的に更新される別のテーブルに「キャッシュ」することです。

キャッシュが(独立ビュー、または3組合等、単一のキャッシュテーブルにマージ)完全なクエリに、またはその下位区分のいずれかに、異なるレベルで行うことができる

本の生存率オプションは、わずかに古くなったデータを表示できるかどうかによって異なります。データの一部だけでは、クエリに含まれるテーブル/ビューのサブセットだけをキャッシュすることを意味する場合があります。

+0

提案をいただきありがとうございます。現在ははるかに高速です。私は定期的に別のテーブルに組合をキャッシュしていますが、それは0.4秒です。しかし、結果を注文すると、 'Copy to tmp table'のボトルネックになっているようです。それを改善する方法はありますか? – Ripptor

関連する問題