私はNewsStoriesテーブルを持っていますが、それは私がいくつかの関連テーブルと結合したままです。各ニュース記事には、複数の画像、カテゴリ、およびアドレスを含めることができます。そのため、クエリは基本的に次のようになります。
SELECT * FROM NewStories
LEFT JOIN Images ON Newstories.id=Images.story_id
LEFT JOIN Categories ON NewsStories.id=Categories.story_id
LEFT JOIN Addresses ON NewsStories.id=Addresses.story_id
WHERE ...
通常、ストーリーごとにいくつかの画像と住所、および1つまたは2つのカテゴリがあります。 NewsStoriesテーブルには約10,000の記事があります。
問題は、パフォーマンスがかなり遅いことです(15〜20秒程度ですが、かなり変動しますが、5秒程度にまで低下することもあります)。
それをスピードアップするためにクエリを体系化するより良い方法があるかどうか私は不思議に思っていました(私はSQLについてはかなり新しいです)。
特に、あるストーリーの行数に、画像数×アドレス数×カテゴリ数を掛けたのは、非常に無駄が多いようです。
私は本質的に、ニュースストーリーの特性をフロントエンドで操作できる単一のオブジェクトに再構築しようとしています。
これが説明です(フォーマットが正しく出てこない場合は謝罪)。 「Using where」であれば、アドレスを正しく索引付けしていないと思います。あれは正しいですか?
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE Addresses ALL NULL NULL NULL NULL 6640 Using where
1 SIMPLE NewsStories eq_ref PRIMARY PRIMARY 767 NewsStories.Addresses.story_id 1 Using where
1 SIMPLE Images ref PRIMARY PRIMARY 767 NewsStories.NewsStories.id 1 Using index
1 SIMPLE Categories ref PRIMARY PRIMARY 767 NewsStories.NewStories.id 1
CREATE [UNIQUE | FULLTEXT | SPATIAL]インデックスindex_name [index_type] ON tbl_name(index_col_name、...) [index_type]
index_col_name: col_name [(length)] [ASC | DESC]
index_type: 使用中{BTREE |ハッシュ}
すべてのテーブルのすべての列を本当に選択する必要があるかどうかを確認しますか?そうでない場合は、必要な列だけを選択するようにしてください。使用しないでください。選択*
本当にLEFT JOINSが必要かどうかを再確認し、必要でなければINNER JOINを使用してください。
クエリを調整した後もパフォーマンスが依然として問題になる場合は、結合を排除するためにスキーマを非正規化することを検討してください。
sphinxsearchやmemcachedなどのキャッシュアプリケーションを使用してデータベースの負荷を減らすことを検討することもできます。
実際のテーブルではなく、ビューへの結合がないことを確認します。
参照先
http://dev.mysql.com/doc/refman/5.0/en/create-index.html
Check none of your joins are to views rather than actual tables
。 (そして) - NullPointer
テーブルに適切なインデックスが付けられていることを確認してください。データを選択するために使用するすべての列にインデックスを付ける必要があります。そうしないと、MySQLはテーブル内のすべての行を通過します。
クエリを説明してみてください(EXPLAIN SELECT * FROM ...etc
MySQLコンソールで、MySQLがテーブルを内部でどのように処理するかを確認します。さらに助けを求めるためにあなたの質問に結果を貼り付けてください。