【问题标题】:MySQL database: high performance random lookupsMySQL 数据库:高性能随机查找
【发布时间】:2012-05-18 20:44:19
【问题描述】:

我正在设计一个高性能可扩展数据库的后端,它需要非常快速地选择某些类别中的随机行。概括地说,有一个巨大的行表,每行都有一个“类别”字段,然后可能有 1000 万行,其中存在多达 500 个不同的类别。

在挑选这些时,我首先想到的提高性能是创建一个单独的查找表,仅按类别索引,以便伪代码类似于:

  • 生成介于 0 和 lookup_table 中类别为“example”的行数之间的随机数

  • 从lookup_table 中选择行 WHERE category='example' LIMIT random_number,1

这将使用索引生成匹配行的行数,然后随机选择一个并将其取出。事实证明,在每个类别大约 20,000 行之后,挑选行需要超过 0.02 秒,这对于同时进行许多类似操作并不理想。

我的第二个想法以及我现在可以运行的是一个单独的数据库或一组查找表,因为一旦我们扩展,数据库就可以进行分片了,每个类别都有一个表。然后随机查找将接近即时,因为它们可以在主键上以表计数中的随机数执行。

如果这里有类似经历的任何巫师对此有任何想法可以分享,或者如果我缺少一个可以提供帮助的功能,我将不胜感激。我考虑将表划分为 500 个奇怪的类别,但它似乎对这种情况没有多大用处。

谢谢!

编辑另一个很大程度上影响设计的考虑因素是每个项目可能有多个类别,并且需要能够被其中的任何一个随机选择。

【问题讨论】:

    标签: php mysql performance scalability


    【解决方案1】:

    不使用 LIMIT,而是将新列 rnd 添加到浮点类型的查找表中。在 (category, rnd) 上创建一个索引并使用UPDATE table SET rnd = RAND() 对其进行初始化。然后使用:

    SET $rndValue = RAND();
    SELECT id FROM lookup_table WHERE category = 'example' AND rnd < @rndValue ORDER BY `rnd` DESC LIMIT 1;
    

    有效地找到随机行。您可能希望将其放入循环中,因为如果 @rndValue 最终为 0,它将找不到任何行(或者如果该类别中没有对象)。

    【讨论】:

      猜你喜欢
      • 2023-03-08
      • 2011-09-18
      • 2016-10-24
      • 2010-10-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多