2016-04-06 5 views
5

基本的に私は2つのテーブルを持っています。 usersおよびusers_activity。私は、MySQLのテーブルとユーザーの数はほぼ5000を使用します。各ユーザーは、約50-150の活動について、多くの活動をしています。私はユーザーテーブルのリスト(10×10)をフェッチしたいとき、私はユーザーの最後の活動日を表示する必要があります。私はusersテーブルに列last_activityを追加し、次のように選択しない別のテーブルに参加しているかどうか?

::私は新しいアクティビティを追加したい場合は

SELECT * FROM users ORDER BY id DESC, lIMIT 0, 10 

まずオプション:この場合、私は2つのオプションがあります。

INSERT INTO users_activity (userId, date) VALUES(19, "2016-04-06") 

UPDATE users SET last_activity = "2016-04-06" WHERE id = 19 LIMIT 1 

私はlast_activityをキャンセルしたい場合は、次の

DELETE FROM users_activity WHERE activity_id = 100 LIMIT 1 

SELECT date FROM users_activity WHERE userId = 19 ORDER BY DESC LIMIT 1 

この選択を使用して、最後の日付FROM users_activityテーブルをフェッチして、それをupdate SQLで使用できます。

UPDATE users SET last_activity = "2016-04-02" WHERE id = 19 LIMIT 1 

番目のオプション:

私はusersテーブルから列last_activityを削除し、次のように選択し実行します。私は、新しいアクティビティを追加したい場合は

SELECT 
    users.*, 
    users_activity.date 
FROM 
    users 
LEFT JOIN 
    users_activity ON users_activity.userId = users.id 
GROUP BY users.id 
ORDER BY 
    users.id DESC, users_activity.date DESC 
LIMIT 0, 10 

INSERT INTO users_activity (userId, date) VALUES(19, "2016-04-06") 

01をキャンセルしたい場合:

DELETE FROM users_activity WHERE activity_id = 100 LIMIT 1 

私はMysqlを使用しています。どちらの表もinnoDBです。

この場合、どのように私をお勧めしますか、またその理由は何ですか?

答えて

1

まず、あなたの挿入文の構文が間違っていると言いたいと思います。なぜなら、insert文はwhere節では動作しないからです。 私はあなたを正しく理解していれば、ユーザーの情報とその最後の行動の日付を表示したいと思っています。あなたはそれを次のクエリを行うことができますあなたのテーブルだけでなく、インデックス付き場合:

SELECT u.*, a.action_date FROM users u 
LEFT JOIN users_activity a ON a.userId = u.userId 
GROUP BY a.userId 
ORDER BY a.action_date desc 
LIMIT 0, 10 
1

2つ目のシナリオ、2つのテーブルを使用します。これにより、最後の活動日と活動リストの管理について心配する必要がなくなり、ユーザーごとに左結合とグループ分けでユーザーごとにmax(users_activity_date)を選択することで、最終活動日をいつでも取得できます。

免責事項として、両方を試して、あなたの状況にどのような効果があるかを確認してください。シナリオ1では、レポートクエリにパフォーマンス上の利点がありますが、シナリオ2では、アクティビティトラッキングの更新でパフォーマンスの向上が示されます。パフォーマンスに関する質問があれば、ベストプラクティスやアドバイスは実際の環境でのテストを現実的な負荷に置き換えることはできません。

+1

2番目のオプションの欠点は、あなたが必要とする(これは1回目に比べてまともなパフォーマンスを得るために、やや複雑なクエリを必要とすることですオプション1と同じパフォーマンスを得るためにクエリプランで 'Group-byのインデックスを使用する 'ようにしてください)。 – Vatev

+0

@Vatev私は同意しますが、各ステップでは2番目のシナリオでは1つの操作が必要です。また、彼は一度に10人のユーザーしか選択していません。ユーザーの活動を追跡している場合は、アクティビティの追跡がレポートコンポーネントよりもパフォーマンスが高いことが重要です。 – Kateract

+2

私の経験では、ほとんどの場合、読み込みを簡単にし、書き込みを複雑にする方が良いです。 'users'に参加するときに' last_acticity'が必要なクエリの数によって異なります。 – Vatev

関連する問題