Mysql:索引计数查询与维护摘要表

时间:2017-07-27 13:37:32

标签: mysql database database-performance

我正在开发一个电子商务网站,用户可以对可用产品表现出兴趣,我们将其存储在mysql表中。此Leads表由数百万条记录组成,每秒增长8条记录。表结构如下:

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个潜在客户。我有以下方法来实现这个:

  1. 选择查询以计算Leads表中当天的记录数,并检查<插入前20。

  2. 维护一个DailyLeadCount表,其中包含特定日期的每个userId的潜在客户数。表结构:

    UserId | Date | Count
    

    表架构:

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

    我会在插入Leads表之前检查此表中的计数,并在插入后更新此计数。此外,由于此表中只有一天数据有用,我将创建一个作业以便每天存档。

  3. 哪种方法更好?是否在Leads表上运行select查询以获得比插入/更新更重的计数并在DailyLeadCount表上选择查询?

    是否值得每天维护和存档一张桌子?

    还有其他方法可以解决这个问题吗?

1 个答案:

答案 0 :(得分:0)

更改

KEY `ix_leads_userid` (`UserID`) USING BTREE

INDEX(UserID, RequestDateTime)

然后在

时向用户吐口水
( 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毫秒”则不太好。