Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 随机化大数据集_Mysql_Random - Fatal编程技术网

Mysql 随机化大数据集

Mysql 随机化大数据集,mysql,random,Mysql,Random,我试图找到一种方法,从一个大的数据集中随机选择 我们预计该集将增长到约500K记录,因此找到一种在该集增长时保持良好性能的方法非常重要 我尝试了一种来自的技术:但它不是完全随机的,它不能很好地处理限制条款,你不可能总是得到你想要的记录数 所以我想,因为PK是自动递增的,所以我只需要生成一个随机id的列表,并使用IN子句来选择我想要的行。这种方法的问题是,有时我需要一组随机的数据,其中的记录具有特定的状态,这种状态最多占整个数据集的5%。为了使这项工作,我首先需要找出我可以使用的具有特定状态的ID

我试图找到一种方法,从一个大的数据集中随机选择

我们预计该集将增长到约500K记录,因此找到一种在该集增长时保持良好性能的方法非常重要

我尝试了一种来自的技术:但它不是完全随机的,它不能很好地处理限制条款,你不可能总是得到你想要的记录数

所以我想,因为PK是自动递增的,所以我只需要生成一个随机id的列表,并使用IN子句来选择我想要的行。这种方法的问题是,有时我需要一组随机的数据,其中的记录具有特定的状态,这种状态最多占整个数据集的5%。为了使这项工作,我首先需要找出我可以使用的具有特定状态的ID,所以这也行不通

我使用的是mysql 5.1.46,MyISAM存储引擎。 要知道选择随机行的查询将经常运行,并且它从中选择的表将经常附加到该表中,这一点可能很重要


任何帮助都将不胜感激

由Jan Kneschke签出。。。它在解释解决这个问题的不同方法的优缺点方面做得很好…

您可以高效地完成这项工作,但您必须在两个查询中完成

首先获取一个随机偏移量,该偏移量按与5%条件匹配的行数缩放:

SELECT ROUND(RAND() * (SELECT COUNT(*) FROM MyTable WHERE ...conditions...))
这将返回一个整数。接下来,将整数用作极限表达式中的偏移量:

SELECT * FROM MyTable WHERE ...conditions... LIMIT 1 OFFSET ?

并非每个问题都必须在一个SQL查询中解决。

您可以通过一些非规范化来解决这个问题:

构建包含与数据表相同的PKEY和状态的辅助表 添加并填充一个状态组列,该列将是一种子pkey,您可以根据单个状态自动为自己编号1-based autoincrement 当您不需要筛选时,可以在pkey上生成rand s,如上所述。当您确实需要筛选时,根据您感兴趣的特定状态的StatusPkeys生成rands


有几种方法可以构建此表。你可以有一个程序,你运行的时间间隔或你可以做它的现场。但是,后者会对性能造成影响,因为计算StatusPkey可能会很昂贵。

因此,您的意思是执行两次查询。然后斜过几十万行?我不认为这是有效率的。。。使用双查询方法的更好方法是添加WHERE id>=?将1限制为第二个查询。这样,它就不需要加载前n行来查找所需的行,它可以缩短该步骤并应用重大优化…这种方法的问题是一次只能检索一条记录。当您增加限制时,它不再是一个随机集,只是偏移量是随机的。@ircmaxell:偏移量不是id值。使用WHERE id>=?是非随机的,以更高的频率拾取间距后出现的行。@Dennis Haarbrink:对,这种技术对于一次选取一个随机行很有用。如果我们想要选取几行,该怎么办?本文的第一句话是:对于第一个示例,我们假设be ID从1开始,并且在1和ID的最大值之间没有孔。。这正是我面临的问题:我确实有洞。往下读。有一整节是关于在数字中添加洞,以及使用触发器维护洞表的…我明白了。。判断得太快了!他建议采用与保罗·萨西克相同的方法,所以我想我们在这方面做得不错!我也想到了这种方法,但觉得太贵了。我当时没有意识到它最多只占总数的5%,我认为它会更大。因此,我认为这是我将采取的方法。我将为此创建一个后台进程,但我不想让前端的性能受到影响。如何每隔一段时间填充或重新创建表?一天一次还是一小时一次?或者它需要在现场附近吗?这就是我打算做的,我将为此安装一个crontab。我想我可以保持相当高的更新频率,比如说,每五分钟更新一次,因为我可以在状态改变时注册。所以我所要做的就是检查“脏”标志并重新填充表格!如果我能跟踪准确的状态更新,我甚至可以只做更新。
Pkey    Status    StatusPkey
1       A         1
2       A         2
3       B         1
4       B         2
5       C         1
...     C         ...
n       C         m (where m = # of C statuses)