服务使用限制器实现

时间:2011-03-09 11:44:57

标签: java mysql

我需要为多个客户限制多个服务使用。例如,客户 customer1 每月最多可发送1000条短信。我的实现基于一个包含3列的MySQL表:

date TIMESTAMP
name VARCHAR(128)
value INTEGER

对于每个服务使用(发送SMS),将向表中插入一行。 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。

提前致谢

3 个答案:

答案 0 :(得分:1)

两列上都应该有一个索引,而不是每列上都有两个索引。这应该使查询非常快。

如果它仍然没有,那么您可以使用具有月份,名称和值的表,并在每次发送SMS时递增当前月份的值。这将从查询中删除总和。尽管如此,它仍然需要(月份,名称)上的索引尽可能快。

答案 1 :(得分:0)

值得尝试用“喜欢”替换你的“=”。不知道为什么,但在过去我看到这个比varchar列上的“=”运算符快得多。

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

评论后编辑:

好的,现在我可以重新创建您的问题 - 第一次运行查询时,大约需要0.03秒,后续运行查询需要0.001秒。插入新记录会导致查询恢复为0.03秒。

建议的解决方案: COUNT没有显示相同的减速。我会改变业务逻辑,所以每次用户发送和短信你插入一个值为“1”的记录;如果消息是多部分消息,则只需插入两行。 将“sum”替换为“count”。 我已将此应用于我的测试数据,即使在插入新记录后,“count”查询也会在0.001秒内返回。

答案 2 :(得分: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;

查找自%date以来的服务使用情况:

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 - value2

这样我就需要交易。我可能会将其实现为存储过程。

仍然赞赏任何其他提示: - )