2017-04-25 10 views
0

システムにはuser_posts(post)& user_post_like_counts(likesの数)という2つのテーブルがあります。 投稿を並べ替える(asc/desc)関数を実装しました。ORDER BYを最適化して2つの大きなテーブルを結合する

問題は:データテーブルが約200万レコードの場合です。 SQLを実行するには長い時間がかかります(2分)。

SELECT DISTINCT user_posts.*, `user_post_like_counts`.total_count 
FROM `user_posts` 
LEFT OUTER JOIN `user_post_like_counts` ON `user_post_like_counts`.`user_post_id` = `user_posts`.`id` 
WHERE `user_posts`.`deleted_at` IS NULL 
     AND `user_posts`.`created_at` <= '2017-04-24 01:47:00' 
ORDER BY `user_post_like_counts`.total_count DESC 
LIMIT 50 
OFFSET 0; 

私はちょうど実行するために1秒よりかからことにより、上記のSQLを順序を削除場合。

これは、このSQLクエリのEXPLAINです。

https://i.stack.imgur.com/sBK4j.png

私は本当にすべての助けに感謝。 おかげ

+1

MySql <> Sql Server。 –

+0

あなたがページングを使用しているので、あなたはhvによって注文を使用します。私は問題がdistinct.why 2つのテーブル間の関係ならdistinct.wt kindを使用すると思います。 – KumarHarsh

+0

user_post_like_countsテーブルにはどのようなインデックスがあり、それらのフィールドにはどのようなインデックスが含まれていますか? – Shadow

答えて

1

ⅰ)あなたHVは良いですが、ページングを使用するので、順を削除することはできません

II)を取り外し明確な

III)「*」削除し、代わりに

のみを選択したカラム名を使用します

iii)希望user_post_like_countsuser_post_idおよびuser_postsidは両方ともCIです。

IV)TOTAL_COUNTは常にDESCによって順番になりますから、それはNCIとインデックスレベルの降順によって順序自体

あなたがdeleted_atを使用することにより、ほぼすべてのレコード(80%)を取得した場合V)、その後必要NULLではありませんします削除されたテーブルのインデックスを作成します。

vi)ポストテーブルには多くのレコードが含まれているため、最も重要なテーブルです。 削除されたレコードを同じテーブルに保存しないでください。別々の履歴テーブルを作成してください。 これは1つの重要な要因です

vii)だから私は、index.inludeポストテーブルのそれらの列をカバーしてcreated_atでNCIを作成すると思います。

関連する問題