MySQL数据库:高性能随机查找

时间:2012-05-10 09:37:19

标签: php mysql performance scalability

我正在设计一个高性能可扩展数据库的后端,该数据库需要非常快速地选择某些类别中的随机行。为了对此进行总体描述,有一个巨大的行表,每个行都有一个“类别”字段,然后可能有1000万行,最多可存在500个不同的类别。

我首先考虑提高选择这些的性能是创建一个单独的查找表,只按类别索引,以便伪代码类似于:

  • 在lookup_table

  • 中生成介于0和行数'row'之间的行数的随机数
  • 从lookup_table中选择行WHERE category ='example'LIMIT random_number,1

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

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

如果有类似经验的巫师有任何想法可以分享,或者如果有一个我遗漏的功能会有所帮助,我会非常感激。我考虑将表格划分为500个奇数类别,但似乎对这种情况没什么用处。

谢谢!

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

1 个答案:

答案 0 :(得分:1)

不是使用LIMIT,而是使用float类型将新列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,则不会找到任何行(或者如果该类别中没有对象)。