有没有人有从具有+100,000,000(1 亿)条记录的索引中获取随机结果的经验。
目标是获得 30 个随机排序的结果,每秒至少 100 次。
实际上我的记录在 MySQL 中,但是从大表中选择 ORDER BY RAND() 是杀死 MySQL 的最简单方法。
Sphinxsearch 或任何你推荐的东西?
有没有人有从具有+100,000,000(1 亿)条记录的索引中获取随机结果的经验。
目标是获得 30 个随机排序的结果,每秒至少 100 次。
实际上我的记录在 MySQL 中,但是从大表中选择 ORDER BY RAND() 是杀死 MySQL 的最简单方法。
Sphinxsearch 或任何你推荐的东西?
我没有那么大的索引可以尝试。
barry@server:~/modules/sphinx-2.0.1-beta/api# time php test.php -i gi_stemmed --sortby @random --select id
Query '' retrieved 20 of 3067775 matches in 0.081 sec.
Query stats:
Matches:
<SNIP>
real 0m0.100s
user 0m0.010s
sys 0m0.010s
这是在一个相当强大的专用服务器上 - 提供实时查询(~20qps)
但老实说,如果您不需要过滤(即每个查询都有一个“WHERE”子句),您可以设置一个返回随机结果的系统 - 可以使用 mysql 执行此操作。仅使用 ORDER BY RAND() 是邪恶的(虽然 sphinx 在排序方面比 mysql 更好,但仍然在做基本相同的事情)。
您的数据有多“稀疏”?如果你的大部分 id 都被使用了,可以做类似的事情
$ids = array();
$max = getOne("SELECT MAX(id) FROM table");
foreach(range(1,30) as $idx) {
$ids[] = rand(1,$max);
}
$query = "SELECT * FROM table WHERE id IN (".implode(',',$ids).")";
(可能想在 php 中使用 shuffle() 之后的结果,因为您很可能按 id 顺序从 mysql 中获取结果)
这将更有效率。如果您确实有漏洞,也许只需查找 33 行。有时会得到比需要更多的东西,(只是丢弃),但大多数时候你仍然应该得到 30 个。
(当然,您可以将“$max”缓存在某处,因此不必一直查找它。)
否则,您可以设置一个专用的“洗牌”列表。基本上是一个 FIFO 缓冲区,有一个线程,用随机结果填充它(可能使用上述系统,一次使用 3000 个 id),然后消费者直接从这个队列中读取随机结果。
FIFO,用 mysql 实现并不特别容易,所以可能使用不同的系统 - 可能是 redis,甚至只是 memcache。