2017-07-27 10 views
0

私は利用可能な製品に関心を示すことができる電子商取引のWebサイトに取り組んでおり、私たちはmysqlテーブルの先頭にそれを保存します。このLeadsテーブルは、数百万のレコードで構成され、1秒あたり8レコード増加します。次のようにテーブルの構造は以下の通りである:Mysql:インデックス付きカウントクエリとサマリーテーブルの保守

LeadId | ProductId | UserId | RequestDate(DateTime) 

テーブルスキーマ:

`id` int(11) NOT NULL AUTO_INCREMENT, 
`ProductId` int(11) DEFAULT NULL, 
`UserID` int(11) NOT NULL, 
`RequestDateTime` datetime(3) NOT NULL, 
PRIMARY KEY (`id`), 
KEY `ix_leads_requestdatetime` (`RequestDateTime`) USING BTREE, 
KEY `ix_leads_productid` (`ProductId`) USING BTREE, 
KEY `ix_leads_userid` (`UserID`) USING BTREE 

次に、要求が一人のユーザが一日に最大10点のリードを与えるようにすることです。 Leads表にその日のレコードの数をカウントし、< 20場合は、挿入する前にチェックするために

  1. 選択クエリ:私はこれを実装するためのアプローチを以下しています。

  2. の特定の日付のリード数を含むDailyLeadCountテーブルを維持します。テーブルの構造:

    UserId | Date | Count 
    

    テーブルスキーマ:私はLeadsテーブルに挿入する前に、この表の数をチェックし、それに応じて挿入した後、この数を更新します

    `RequestDate` date NOT NULL, 
    `UserId` int(11) NOT NULL, 
    `LeadCount` smallint(6) NOT NULL, 
    PRIMARY KEY (`RequestDate`,`UserId`) 
    

    。また、この表では1日のデータだけが有用なので、毎日アーカイブするジョブを作成します。

どのアプローチが良いですか? Leadsテーブルで選択クエリを実行すると、挿入/更新より重くなり、DailyLeadCountテーブルのクエリを選択するよりも重いのですか?

毎日テーブルを管理し、アーカイブする価値はありますか?

これを処理する他の方法はありますか?

INDEX(UserID, RequestDateTime) 

+0

3番目のオプションは、サブクエリでwhere句にチェックを含めるようにinsert文を作成することです。インデックスを含むテーブルスキーマを表示できますか? –

+0

@SloanThrasherテーブルスキーマを追加しました。また、ストアド・プロシージャ内にある場合は、where句で副問合せを追加することは、パフォーマンスに関してアプローチ-1と同じです。ではない? – ctor

+0

正確には一致しません。 #1では、selectとinsertの2つのクエリがあります。調べる最も良い方法は、両方のクエリを記述し、サーバーがどのように作業を実行するかを理解するためにExplainを使用することです。 –

答えて

0

変更

KEY `ix_leads_userid` (`UserID`) USING BTREE 

その後、クエリをリアルタイムに行うのに十分に高速になりますとき

(SELECT COUNT(*) FROM Leads WHERE UserID = 1234 
     AND RequestDateTime > NOW() - INTERVAL 24 HOUR 
) >= 10 

ユーザーに唾を吐きます。

昨日と今の間にカウントされます。これはあなたが望むものと正確に異なる場合があります。 「真夜中昨日から」場合

 AND RequestDateTime > CURDATE() 

 AND RequestDateTime > CURDATE() - INTERVAL 1 DAY 

あなたは深夜のためタイムゾーンを使用したい場合は、それを取得、代わりに、あなたは時計が真夜中に今朝を開始する場合面倒だ。

潜在的な問題:何とかリードをバッチ処理できる場合、同じミリ秒で複数のリードを挿入できます。 (私が気づいているのはDATETIME(3)です)

「昨日」をチェックする必要がある場合は、サマリーテーブルの考え方が適していますが、「最後の86400000ミリ秒」ではあまり適していません。

+0

サマリーテーブルが良い時は、ちょっと混乱しています。過去24時間ではなく、「現在の日付」のカウントを確認する必要があります(つまり、今日の深夜の時計のリセット)。あなたは、要約は最後の "x"単位時間には機能しませんが、 "最後の日付"についてはよりうまくいくと言っています。私の場合(現在の日付)には役に立たないでしょうか? – ctor

+0

「今日」だけを見ている場合、前日を要約する必要はありません。今日の深夜には「今日」を要約するのが最善です。 –

関連する問題