1

メインホームページに表示するFeaturedContentを見つけるニュースサイトのクエリに取り組んでいます。このようにマークされたコンテンツは「FeaturedContent」としてタグ付けされ、「ホームページ」によって注目のテーブルで並べ替えられます。現在、目的の出力がありますが、クエリは3秒以上で実行されるため、短縮する必要があります。次のようなクエリをどのように最適化しますか?

編集:提案されているように、毎分、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つのテーブルの単純なビューです。

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

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

編集:参照用のテーブルサイズ:
タグの関係:197,411
タグ:16,897
ストーリー:51,801
画像:28,383
ビデオ:2,408
注目:13

4

1 に答える 1

1

クエリを最適化するだけではあまり役に立たないと思います。最初に考えたのは、それ自体がUNIONで構成されているサブクエリを結合することだけが、パフォーマンスの二重のボトルネックであるということです。

データベース構造を変更するオプションがある場合は、3つのテーブルをマージし、stories見た目imagesvideos非常に似ている場合は1つにマージしてtype ENUM('story', 'image', 'video')、レコードを区別することをお勧めします。これにより、サブクエリとユニオンの両方が削除されます。

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

完全なテーブル構造とデータの再パーティション化を知らなければ、これはかなりトリッキーな問題です。

既存のデータベースに変更を加える必要がない別のオプション(特にデータベースが既に本番環境にある場合)は、この情報を別のテーブルに「キャッシュ」し、cronジョブによって定期的に更新されます。

キャッシングは、クエリ全体またはそのサブパート(独立したビュー、または3つのユニオンが単一のキャッシュテーブルにマージされるなど)のいずれかで、さまざまなレベルで実行できます。

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

于 2011-06-17T18:41:43.950 に答える