0

有没有人有从具有+100,000,000(1 亿)条记录的索引中获取随机结果的经验。

目标是获得 30 个随机排序的结果,每秒至少 100 次。

实际上我的记录在 MySQL 中,但是从大表中选择 ORDER BY RAND() 是杀死 MySQL 的最简单方法。

Sphinxsearch 或任何你推荐的东西?

4

1 回答 1

1

我没有那么大的索引可以尝试。

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。

于 2012-08-17T17:03:02.827 回答