大数据库快速mysql随机加权选择

[复制链接]
查看1 | 回复0 | 2021-12-3 09:08:52 | 显示全部楼层 |阅读模式
我建立一个网站,我需要从数据库中选择随机加权记录 。大数据库快速mysql随机加权选择
还有就是代码SQL : select one row randomly, but taking into account a weight
SELECT t.*, RAND() * t.weight AS w FROM table t ORDER BY w DESC LIMIT 1
它适用于记录小样本罚款文档片断。
尝试接近100万条记录时,它在本地机器上变慢(1.3 - 1.8秒) ,我想我会在更大的机器上花费更长的时间。
它如何优化? 有没有更好的方法随机选择加权记录?
我的尝试是定期计算权重,将它们存储在单独的表中,选择随机数programmaticaly并搜索最接近该记录的记录。

您可以根据权重对数据进行分区,然后随机选择一个分区。
确定要使用的分区:O(n)的
SELECT Weight, FLOOR(RAND()*COUNT(*)) as Target FROM test GROUP BY Weight ORDER BY RAND()*(Weight)*count(Weight)/100 DESC LIMIT 1;
使用权,并从以前的查询目标得到的结果:O(日志(n))的
SELECT test.* FROM test WHERE Weight = $Weight LIMIT $Target, 1
测试:
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)运行时间。

我与第一个查询中(6.089 s)运行测试表800万行和(0.001 s)
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题

0

回帖

49

积分

新手上路

Rank: 1

积分
49
热门排行