在我的postgres数据库中,我有以下关系(为了这个问题而简化):
Objects (currently has about 250,000 records)
-------
n_id
n_store_object_id (references store.n_id, 1-to-1 relationship, some objects don't have store records)
n_media_id (references media.n_id, 1-to-1 relationship, some objects don't have media records)
Store (currently has about 100,000 records)
-----
n_id
t_name,
t_description,
n_status,
t_tag
Media
-----
n_id
t_media_path
到目前为止,这么好。当我需要查询数据时,我会运行此操作(请注意最后的limit 2
,作为要求的一部分):
select
o.n_id,
s.t_name,
s.t_description,
me.t_media_path
from
objects o
join store s on (o.n_store_object_id = s.n_id and s.n_status > 0 and s.t_tag is not null)
join media me on o.n_media_id = me.n_id
limit
2
这样可以正常工作,并按预期返回两个条目。这个执行时间大约是20毫秒 - 就好了。
现在每次查询运行时我需要输入2个随机条目。我以为我会添加order by random()
,就像这样:
select
o.n_id,
s.t_name,
s.t_description,
me.t_media_path
from
objects o
join store s on (o.n_store_object_id = s.n_id and s.n_status > 0 and s.t_tag is not null)
join media me on o.n_media_id = me.n_id
order by
random()
limit
2
虽然这给出了正确的结果,但现在执行时间约为2,500毫秒(超过2秒)。这显然是不可接受的,因为它是为Web应用程序中的页面获取数据而运行的大量查询之一。
所以,问题是:如何获得随机条目,如上所述,但仍然将执行时间保持在一段合理的时间内(即100毫秒以下是可以接受的)?
答案 0 :(得分:3)
当然,在获得第一行之前,需要根据随机标准对整个事物进行排序。也许您可以使用random()
中的offset
代替?
答案 1 :(得分:1)
以下是有关此主题的一些以前的工作可能会有所帮助:
http://blog.rhodiumtoad.org.uk/2009/03/08/selecting-random-rows-from-a-table/
答案 2 :(得分:0)
我认为你最好首先选择随机对象,然后在选择后对这些对象进行连接。即,查询一次以选择随机对象,然后再次查询以仅加入所选择的那些对象。
答案 3 :(得分:0)
看起来你的问题是这样的:你有一个250,000行的表,需要两个随机行。因此,您必须生成250,000个随机数,然后按行数对行进行排序。两秒钟这样做对我来说似乎很快。
加速选择的唯一真正方法是不必提供250,000个随机数,而是通过索引查找行。
我认为您必须更改表架构以针对此情况进行优化。怎么样:
number
。number % 1000
number % 1000
等于随机数的行
介于0和999之间(这应该会触及索引并随机加载
数据库的一部分)如果这仍然不够随机(因为行将始终配对具有相同的“散列”),您可能可以执行两个随机行的并集,或者在查询中使用OR子句并生成两个随机密钥
希望沿着这些方向发展的东西可以非常快速且随意地随机。