大型数据库上的快速mysql随机加权选择
我建立了一个网站,我需要选择随机加权记录 从数据库 里面有一段代码 它在小样本记录上运行良好 当尝试接近1百万条记录时,速度会变慢(1.3-1.8秒) 在我本地的机器上,我想在更大的电视机上我会花更长的时间 如何对其进行优化? 是否有更好的方法随机选择加权记录大型数据库上的快速mysql随机加权选择,mysql,sql,random,Mysql,Sql,Random,我建立了一个网站,我需要选择随机加权记录 从数据库 里面有一段代码 它在小样本记录上运行良好 当尝试接近1百万条记录时,速度会变慢(1.3-1.8秒) 在我本地的机器上,我想在更大的电视机上我会花更长的时间 如何对其进行优化? 是否有更好的方法随机选择加权记录 我的尝试是定期计算权重,将它们存储在单独的表中,选择random number programmaticaly并搜索与该数字最接近的记录。您可以根据权重对数据进行分区,然后随机选择一个分区 确定要使用的分区:O(n) 使用上一次查询中的权
我的尝试是定期计算权重,将它们存储在单独的表中,选择random number programmaticaly并搜索与该数字最接近的记录。您可以根据权重对数据进行分区,然后随机选择一个分区 确定要使用的分区:O(n) 使用上一次查询中的权重和目标来获得结果:O(Log(n)) 测试它:
CREATE TABLE `test` (
`Id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`Weight` int(11) NOT NULL,
PRIMARY KEY (`Id`),
KEY `Weight` (`Weight`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
insert into test (Weight) ( select FLOOR(RAND()*1000) );
运行20次以创建100万个测试行:
insert into test (Weight) select FLOOR(rand()*1000) as Weight from test;
由于GROUP BY,第一个查询在O(n)中运行。如果您维护第二个表来跟踪每个重量的计数,则可以将其记录到log(n)运行时间
在我的数据库中,测试表中有800万行,第一个查询在
(6.089 s)
中运行,第二个查询在(0.001 s)
中首先获取所有权重的总和,以便您可以计算动态选择每一行的概率
SELECT SUM(weight) FROM t;
我假设总和可以通过名为@TOTAL_WEIGHT的mysql变量访问
SELECT t.*
FROM t
WHERE RAND() <= (weight / @TOTAL_WEIGHT)
ORDER BY RAND()
LIMIT 1;
选择t.*
从t
这在哪里回答了你的问题?
insert into test (Weight) select FLOOR(rand()*1000) as Weight from test;
SELECT SUM(weight) FROM t;
SELECT t.*
FROM t
WHERE RAND() <= (weight / @TOTAL_WEIGHT)
ORDER BY RAND()
LIMIT 1;