php – 高性能MySQL随机非顺序行

我试图从表中获取随机行,数据不会改变.我读过人们尝试ORDER BY RAND(),这对大型数据集来说很糟糕,并且不能很好地扩展.

我也看到了解决方案是让sql在最小/最大范围之间得到一个随机行,如下所示:FLOOR(MAX(needed_id)* RAND)但这只有当行是顺序时才会起作用:1,2, 3,4,5,6,7,8,9,10.

我需要提取的数据不是连续的,例如:1,2,3,4,10,11,12,13

所以我认为有两种解决方案:

第一解决方
继续运行:FLOOR(MAX(needed_id)* RAND)直到我收到一排正确的类型(1/6机会)

第二解决方
创建一个重复的表(因为我的数据永远不会改变),如下所示:

temp_id | needed_id | type 
1            1          1
2            4          1
3            7          2
3            8          2

所以我可以使用这个方法拉出一个随机的temp_id:FLOOR(MAX(temp_id)* RAND) – WHERE type = 1

你怎么看?我可能会运行第一个解决方案大约6次,直到我收到正确的行,但在第二个解决方案中它会立即工作但需要另一个表.

解决方法:

你的陈述

but this would only work when the rows are sequential:

不完全正确:floor()和max()示例适用于非连续行,因为你会做类似的事情

WHERE id> = FLOOR(RAND()* MAX(id))LIMIT 1

所以你把最接近的ID带到你得到的随机命中.

对于直接在序列中存在较大间隙之后的命中,这确实略有偏好,但这可能不会太糟糕,具体取决于您的数据集.

因此,根据您对这种轻微偏好所带来的问题,您的数据集是如何等等,这仍然是最好的解决方案.

因为有些人不清楚,功能的使用不是问题:

MAX在索引字段上很快.您不需要计算所有行(在innoDB上慢),您只需要遍历您的BTREE索引,因此您将在日志时间中找到此值.这几乎是即时的

FLOOR只是一个在线性时间内执行的数学函数.就像兰德一样.请注意,由于兰德,ORDER BY rand()并不慢,但因为你需要订购完整的表格!这不是兰特的问题,而是秩序问题.

现在您有一个查询,它执行以下操作:

WHERE id >= 48 LIMIT 1

哪个在索引字段上非常快.请记住,你没有通过任何类型的表扫描得到那个48(一个例子).

相关文章

统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...
统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...
前言 之前做了微信登录,所以总结一下微信授权登录并获取用户...
FastAdmin是我第一个接触的后台管理系统框架。FastAdmin是一...
之前公司需要一个内部的通讯软件,就叫我做一个。通讯软件嘛...
统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...