MySQL随机出现4亿多行的差距

时间:2012-05-12 02:33:18

标签: mysql random solr

我一直坚持要求,因为我觉得这个问题问得那么多,但仍然缺乏明确的答案:

Objects 表:40M +行填充UPC,EIN,ISBN作为obj_id主键。间隙

* Obj_Cat * table:将对象链接到类别。列的| obj_id | cat_id |

问题:返回5个非连续随机obj_id的最佳方法是什么?有没有比我列出的更好的方式?

解决方案1: SELECT objects.obj_id FROM objects left join obj_cat on objects.obj_id=obj_cat.obj_id WHERE obj_cat.cat_id=cat_id ORDER BY RAND() LIMIT 1;运行5次

  • 大桌很慢。

解决方案2: SELECT obj_id FROM objects WHERE obj_id >= (SELECT FLOOR( MAX(obj_id) * RAND()) FROM个对象) LIMIT 1;运行5次(不包含obj_cat连接以便更容易理解)

  • 如果您的行无间隙或间隙可忽略不计,则为最佳解决方案。非常快。

  • 不适用于类别,因为编号中不可避免地存在差距。

解决方案3: SELECT FLOOR(RAND() * COUNT(objects.*)) AS偏移FROM objects, obj_cat WHERE objects.obj_id=obj_cat.obj_id AND obj_cat.cat_id=cat_id; SELECT obj_id FROM objects LIMIT $offset, 1运行5次

  • 非常灵活。比解决方案快得多1.适用于差距。但是在40M +行时,单个'LIMIT $ offset,1'仍然需要1分钟。

我使用了解决方案3,但速度很慢。我目前的解决方案是使用Solr randomsortfield,因为很容易在fq中指定我的类别。

Solr解决方案: ?q=*&fl=obj_id&fq=cat:(cat_id)&sort=random_* desc&rows=5

  • 速度非常快,每个类别大约需要45秒,但在运行中会返回5个非顺序结果。

人们在处理大型数据集时是否有更好的方法?我知道这似乎是一个重复的问题,但我想我会用40M +表来贡献我的经验。

1 个答案:

答案 0 :(得分:0)

对于这么大的数据集,你不能像这样进行动态计算。您需要利用时间 - 内存权衡。在obj_cat表中创建一个新的无符号整数索引列,其宽度大于最大行数,并使用随机数填充每一行。这样您就可以简单地生成一个随机数,并直接选择最接近的匹配五次。这比尝试使用ORDER BY RAND()快几个数量级。