2011-03-09 9 views
0

複数のお客様に複数のサービスを使用することを制限する必要があります。たとえば、顧客の顧客1は、月額1000 SMSを送信できます。一つの行がテーブルに挿入される(SMSを送信する)毎にサービス利用のためサービス利用制限ツールの実装

date TIMESTAMP 
name VARCHAR(128) 
value INTEGER

:私の実装は、3列と、ワンMySQLのテーブルに基づいています。 valueは使用回数を保持します(例えば、SMSが2部に分割された場合、value = 2)。 nameにはリミッタ名が含まれます(例:customer1-sms)。サービスは今月使用された回数(2011年3月)を見つけるために

、単純なクエリが実行されます。

SELECT SUM(value) FROM service_usage WHERE name = 'customer1-sms' AND date > '2011-03-01';

問題は、このクエリは(0.3秒)遅いことです。列datenameにインデックスを使用しています。

サービスの使用制限を実装する方法がいくつかありますか?私の要件は、フレキシブルでなければならないということです(例えば、過去10分以内に使用状況を知る必要がある場合、または今月内に別の使用状況を知る必要がある場合など)。私はJavaを使用しています。事前

+0

:-)高く評価されています。データベースを使用していない可能性があります。または、この目的のためにのみ作成された特殊なデータベースを使用します。 –

答えて

0

私の問題の解決策が見つかりました。代わりに、サービス利用の増加を挿入する、私はインクリメント最後のものを挿入します:

 
BEGIN; 

-- select last the value 
SELECT value FROM service_usage WHERE name = %name ORDER BY date ASC LIMIT 1; 

-- insert it to the database 
INSERT INTO service_usage (CURRENT_TIMESTAMP, %name, %value + %increment); 

COMMIT; 

%日からサービスの利用状況を調べるには:

SELECT value AS value1 FROM test WHERE name = %name ORDER BY date DESC LIMIT 1; SELECT value AS value2 FROM test WHERE name = %name AND date <= %date ORDER BY date DESC LIMIT 1;

結果はVALUE1になります - 値2

こうすれば、私は取引が必要になります。私はおそらくそれをストアドプロシージャとして実装します。

任意の追加のヒントは、まだ私はcompletly別のソリューションを受け入れて喜んで

1

ありがとうございます、列のそれぞれに両方の列上の一つの指標ではなく、2つのインデックスを持つ必要があります。これにより、クエリが非常に高速になるはずです。

まだそうでない場合は、月、名前、値の表を使用して、SMSを送信するたびに現在の月の値を増やすことができます。これにより、クエリの合計が削除されます。しかし、できるだけ早く(月、名前)にインデックスが必要です。

+0

私は両方のカラムでもインデックスを試しました。それは役に立ちません。 MySQLは 'name'のインデックスのみを使用し、日付の範囲が大きすぎない場合は' date'インデックスも使用します。私は 'EXPLAIN SELECT ... 'コマンドでこれをチェックしました。 –

+0

月のテーブルを持つソリューションは、私が必要とするほど柔軟ではありません。私はまた、過去24時間以内に使用回数を知る必要があり、過去に引数名と日付を持つ他の動的クエリがあるかもしれません。 –

+0

クエリで終了日を指定しようとしましたか(つまり、 '2011-03-01'と '2011-04-01'の間の日付)、説明プランが変更されている可能性があります。このテーブルの行数は何ですか?スキャンを高速化するために古いエントリ(今月の前)を削除できますか? –

0

"="を "like"に置き換える価値はあります。理由は分かりませんが、これまでvarcharカラムの "="演算子よりもはるかに高速に実行されています。コメントの後に編集

SELECT SUM(value) FROM service_usage WHERE name like 'customer1-sms' AND date > '2011-03-01'; 

さて、私はみかんあなたの問題を再作成することができます - 私は、クエリを実行する最初の時間は、それが周りに0.03秒かかり、クエリの後続の実行は、0.001秒を取ります。新しいレコードを挿入すると、クエリは0.03秒に戻ります。

おすすめの解決策: COUNTは同じスローダウンを表示しません。私はビジネスロジックを変更するので、ユーザーがSMSを送信し、値 "1"のレコードを挿入します。メッセージがマルチパートメッセージの場合は、単に2つの行を挿入します。 "sum"を "count"に置き換えます。 これをテストデータに適用しました。新しいレコードを挿入した後でも、 "count"クエリは0.001秒で戻ります。

+0

これは役に立たなかった。 –

+0

クエリの先頭に「説明」を追加できますか?私はあなたのデータ構造を再作成しようとしましたが、100万行程度のデータを取り込みました。クエリは十分高速です。 –

+0

後続の選択は高速です。しかし、もう1つの行を挿入すると、MySQLはキャッシュされた結果を忘れてしまい、それを再び合計します。 –

関連する問題