我试图从持有约700万条记录表中获取4个随机结果。 另外,我也想从按类别过滤同桌4个随机记录。
现在,你可以想象在桌子上做随机排序这个大导致查询需要几秒钟,这是不理想的。
另外一个方法我想到了non-filtered
的结果集是只让PHP之间选择一些随机数1 - 700万左右,然后做一个IN(...)
通过查询只有抓住这些行-和是的,我知道,这种方法需要注意一点在你可能会小于4,如果与ID的记录不再存在。
然而,上述方法显然不会与类别过滤工作,因为PHP不知道哪一个创纪录的数字属于哪个类别,因此不能选择记录编号可供选择。
是否有更好的方法,我可以做到这一点? 只有这样我能想到的将是存储记录的ID在另一个表中每个类别,然后选择从随机的结果,然后只选择那些记录的ID从主表中的第二查询; 但我敢肯定有一个更好的办法!?
当然,你可以使用RAND()
上使用的查询功能LIMIT
和WHERE
(该类别)。 这不过正如你所指出,需要其由于数据量需要时间,尤其是在你的情况下,数据库的扫描。
您的其他替代方案,再次为你指出的那样,存储ID / CATEGORY_ID另一个表可能证明有点快,但再次,必须有一个LIMIT
和WHERE
该表也将包含的记录相同数量的主表。
一种不同的方法(如适用),将有每个类别的表和存储的标识。 如果您的类别是固定的或不经常改变,那么你应该能够使用这种方法。 在这种情况下,你将有效地删除WHERE
从子句和得到一个RAND()
与LIMIT
每个类别表会更快,因为每个类别表将包含从主表记录的子集。
其他一些替代方案是使用一个键/值对数据库只是该操作。 MongoDB的或谷歌的AppEngine可以与帮助,并非常快。
你也可以去朝着你的MySQL主/从的做法。 从复制的实时内容,但是当你需要进行昂贵的查询您查询的奴隶,而不是主人,从而使负载到不同的机器。
最后,你可以与狮身人面像这是一个更容易安装和维护去。 然后,您可以将每个那些类别查询作为文档的搜索,让狮身人面像随机的结果。 这样,您就抵消这种昂贵的操作,以不同的层,让MySQL的继续进行其他操作。
只是一些需要考虑的问题。
工作把你的随机数的方法
- 在数据库中保存的最大ID。
- 创建一个临时表来存储你的比赛。
- 循环n次执行以下操作
- 产生1和maxId之间的随机数
- 获取更大的记录ID比随机数的第一条记录并将其插入到你的临时表
- 你的临时表现在包含您的随机结果。
或者你可以动态生成SQL与工会做查询一步到位。
SELECT * FROM myTable WHERE ID > RAND() AND Category = zzz LIMIT 1
UNION
SELECT * FROM myTable WHERE ID > RAND() AND Category = zzz LIMIT 1
UNION
SELECT * FROM myTable WHERE ID > RAND() AND Category = zzz LIMIT 1
UNION
SELECT * FROM myTable WHERE ID > RAND() AND Category = zzz LIMIT 1
注:我的SQL可能是无效的,因为我不是一个MySQL的家伙,但理论上应该是合理的
首先,你需要获得的行数......这样的事情
select count(1) from tbl where category = ?
然后选择一个随机数
$offset = rand(1,$rowsNum);
并选择一排偏移
select * FROM tbl LIMIT $offset, 1
这样你不会错过任何标识。 唯一的问题是,你需要运行第二个查询几次。 联盟可以帮助在这种情况下。
对于MySQL,你可以使用
RAND()
SELECT column FROM table
ORDER BY RAND()
LIMIT 4