1

我有一种感觉,我会因为问这个问题而被屠杀,但是就这样……

我每天有 500 万订阅量,并希望/希望在 12 个月内有 5000 万订阅量。我需要非常非常快地更新/计费这些。我已经尝试了我能想到的所有索引和循环排列,但它的 SELECT 查询仍然太慢。也许我的错误是 MySQL 设计,也许是我使用 MySQL 的守护进程,也许仅仅是因为我正在使用 MySQL - 请让我知道你的想法和/或建议。谢谢!

** 订阅表如下所示 **

  • 订阅 ID(PK)
  • 订阅者 ID
  • 服务标识
  • 添加日期
  • current_start_date
  • 当前结束日期
  • bill_date(用于确保两个线程不会同时抢到账单)
  • last_successful_bill_date
  • has_outstanding_balance

** Money-people-owe-me table 看起来像这样*

  • ID
  • subscription_id(英国)
  • 未偿余额
  • next_bill_date
  • number_bill_attempts
  • (相当多的人并不总是付费,我在继续尝试计费时给了他们一段时间的无偿访问权限,但最终我切断了他们的服务)

** 计费守护进程如下所示 **

  • 在多台机器上运行多线程:
  • 对于每项服务
    • stuffToBill[] = SELECT stuff ORDER BY next_bill_date FOR UPDATE LIMIT XXX;
    • UPDATE stuff SET next_bill_date = later WHERE id IN (stuffToBill[ids])
    • 犯罪
    • 让他们排队等待计费工作人员

运行 EXPLAIN 表明我使用了不错的索引,但是 SQL 的细节加上我在多个服务器上运行相同的守护程序这一事实使其锁定/通常使我的 DBM 上的 I/O 队列过载。DBM 是优质硬件。

再次感谢您的建议!

4

1 回答 1

1

您似乎正在使用选择/更新/提交制度来确定要计费的帐户,如下所示:

     SELECT stuff 
   ORDER BY next_bill_date 
 FOR UPDATE 
     LIMIT XXX;

    UPDATE stuff 
       SET next_bill_date = later
     WHERE id IN (stuffToBill[ids]);

    COMMIT;

您的 SELECT 语句可以通过添加一个可行的WHERE子句来改进,该子句只选择即将到期的账单,或者通过一些其他标准。查看所有账单只是为了找到最旧的账单是没有意义的。就像是

  WHERE next_bill_date <= TODAY() + INTERVAL 30 DAYS

可能会成功。如果你做对了,SELECT 查询的复杂性就会降低。如果您正确索引 next_bill_date,您将可以使用索引。

您也可以尝试弄乱LIMIT BY xxxx值的大小。您可能在这里使用了太大的值,并且您的更新速度非常慢。

最后,您将需要考虑进行一些认真的 MySQL 和 InnoDB 调优。控制诸如 RAM 使用之类的预设参数通常不适用于像您这样的生产系统。

于 2013-10-01T22:58:16.237 回答