2

次のような MySQL テーブルがあるとします。このテーブルでは、いつ (Date) ユーザー (User.id) が私の Web サイト (Article.id) で記事を読んだかを追跡します。

------------------------------------------
Article_Impressions
------------------------------------------
date                | user_id | article_id
--------------------+---------+-----------
2013-04-02 15:33:23 | 815     | 2342
2013-04-02 15:38:21 | 815     | 108
2013-04-02 15:39:33 | 161     | 4815
...

特定の日のユーザーあたりの平均セッション時間と同様に、セッション数を特定しようとしています。別の記事の後に 30 分以内に記事が読まれなかった場合、セッションは終了します。

質問

特定の日に行ったセッション数を効率的に判断するにはどうすればよいですか? PHPとMySQLを使用しています。

私の最初のアイデアは、ユーザー別にソートされた、特定の日のすべてのデータを照会することです。次に、各ユーザーを反復処理し、インプレッションが最後のインプレッションから 30 分以内にあるかどうかを確認し、各ユーザーがその日に行ったセッションの合計数を集計します。

私たちのサイトでは 1 日に約 200 万回のインプレッションがあるため、このレポート ジェネレーターを最適化しようとしています。

4

2 に答える 2

1

このクエリを試してください

クエリ 1 :

select 
  @sessionId:=if(@prevUser=user_id AND diff <= 1800 , @sessionId, @sessionId+1) as sessionId,
  @prevUser:=user_id AS user_id, 
  article_id,
  date,
  diff
from 
  (select @sessionId:=0, @prevUser:=0) b
join
  (select 
    TIME_TO_SEC(if(@prevU=user_id, TIMEDIFF(date, @prevD), '00:00')) as diff,
    @prevU:=user_id as user_id,
    @prevD:=date as date,
    article_id
  from 
    tbl 
  join
    (select @prev:=0, @prevU=0)a
  order by 
    user_id, 
    date) a

【結果】

| SESSIONID | USER_ID | ARTICLE_ID |                DATE | DIFF |
-----------------------------------------------------------------
|         1 |     161 |       4815 | 2013-04-02 15:39:33 |    0 |
|         2 |     815 |       2342 | 2013-04-02 15:33:23 |    0 |
|         2 |     815 |        108 | 2013-04-02 15:38:21 |  298 |
|         3 |     815 |        108 | 2013-04-02 16:38:21 | 3600 |

このクエリは、すべての新規ユーザーに対して一意のセッションを返します。質問に記載されている要件に従って、次の記事を読むのが 30 分後である場合は、同じユーザーに対しても一意のセッションを返します。diff 列は、同じユーザーによる 2 つの記事の差 (秒) を返します。これは、sessionId をカウントするのに役立ちます。この結果を使用すると、ユーザーごとの平均時間とセッションごとの合計時間を簡単にカウントできます。

これがお役に立てば幸いです...

SQL フィドル

于 2013-04-03T04:01:26.930 に答える