200万客户在2年内产生20亿订单,但根据历史数据,50%的订单属于100个顶级客户,因此数据在客户id上是极端不平衡的。客户希望通过支付帐户搜索自己的历史订单(一个客户有多个支付帐户,有些客户有数千个支付帐户)。
最难的是顶级客户总是在变化,你不知道哪个客户在未来几个月会有大量的订单。
我需要存储3或4年的订单数据,并为客户提供订单搜索服务。应该如何对数据库和表进行分区?我的意思是,如果在客户的付费帐户上使用哈希,一些数据库将会有大量的数据。我现在有35台服务器,每台服务器上有600G的存储空间。
发布于 2019-07-26 08:40:23
解决方案的关键是:在(?)中将customer_id作为PRIMARY KEY的第一列。包含该列的表。当然,还要在查询中包含AND customer_id = 123。
我不理解"pay accounts",但是如果有acct_id,那么你可能需要
PRIMARY KEY(customer_id, acct_id, ...)由于您可能已经有了id .. AUTO_INCREMENT PRIMARY KEY,因此请更改为
PRIMARY KEY(customer_id, acct_id, id)
INDEX(id) -- sufficient to keep AUTO_INCREMENT happy修改后的PK clusters大多数查询中可能使用/搜索/等等的行,从而加快了它们的速度。
“顶级”客户的行将主要留在buffer_pool中,从而减少对I/O的需求。当一个客户变得更忙时,他的行将超过另一个不太忙的客户。这就是LRU缓存的本质。也就是说,“谁在上面”的转换大部分是自动覆盖的。
"hash“不太可能有帮助。事实上,它可能会造成伤害,因为它是非常随机的,可能会导致在缓存中跳来跳去。(稍后会有更多信息。)
你会清除“旧的”数据(4年后)吗?如果是这样的话,这就带来了另一个问题:从一个巨大的表中对大量行执行DELETEing操作的开销很大。与此相关的是通常提取哪些行的问题--可能只提取“最近”的行?
如果您需要清除,那么按范围分区(TO_DAYS(...))将极大地提高DELETE的速度(通过将其转换为DROP PARTITION)。它可能会对通常只查看“最近”行的问题产生一些影响。
有关时序数据的讨论,请参阅。我建议将TO_DAYS()安排在月份边界上,从而拥有大约50个分区。
有了分区,我仍然会像上面讨论的那样设计PK。但是,在大多数WHERE子句中使用AND date > ...会有所帮助,否则将搜索所有50个分区,这将是一个性能负担。(很难说这是不是一个足够大的负担来反对拥有50个分区。)
你的现在有35台服务器,每台服务器上有600G的存储:你是在说分片还是复制?如果是Replication,,你是指一个主机和34个只读从机吗?
如果由Customer_id进行分片,
https://stackoverflow.com/questions/57203306
复制相似问题