postgresql获取100个随机行

时间:2012-05-30 14:41:40

标签: performance random postgresql-9.1

以下查询在postgresql 9.1上大约需要300-400毫秒。 该表包含~2M行。 这种表现是否合理?可以改进吗?

SELECT "Products"."Id"
      , "Products"."Title"
      , "Products"."ThumbHeight"
      , "Products"."LargeImageWidth"
      , "Products"."LargeImageHeight"
      , "Products"."Url"
      , "Products"."BrowseNodeId"
FROM "Products"
WHERE  "Products"."Id" = ANY(ARRAY(SELECT (random()*2233071)::int
                FROM generate_series(1, 100)));

以下是解释计划:

--------------------------------------------------------------------------------
 Bitmap Heap Scan on "Products"  (cost=60.48..100.46 rows=10 width=268)
   Recheck Cond: ("Id" = ANY ($0))
   InitPlan 1 (returns $0)
     ->  Function Scan on generate_series  (cost=0.00..17.50 rows=1000 width=0)
   ->  Bitmap Index Scan on "Products_pkey"  (cost=0.00..42.97 rows=10 width=0)
     Index Cond: ("Id" = ANY ($0))

解释分析:

Bitmap Heap Scan on "Products"  (cost=60.48..100.46 rows=10 width=268) (actual time=77.702..80.944 rows=100 loops=1)
   Recheck Cond: ("Id" = ANY ($0))
   InitPlan 1 (returns $0)
     ->  Function Scan on generate_series  (cost=0.00..17.50 rows=1000 width=0) (actual time=0.097..0.348 rows=100 loops=1)
   ->  Bitmap Index Scan on "Products_pkey"  (cost=0.00..42.97 rows=10 width=0) (actual time=77.601..77.601 rows=104 loops=1)
         Index Cond: ("Id" = ANY ($0))
 Total runtime: 81.409 ms

Id是主键:     "Products_pkey" PRIMARY KEY, btree ("Id")

谢谢!

2 个答案:

答案 0 :(得分:1)

与您的查询相比,请尝试此操作:

SELECT "Products"."Id"
      , "Products"."Title"
      , "Products"."ThumbHeight"
      , "Products"."LargeImageWidth"
      , "Products"."LargeImageHeight"
      , "Products"."Url"
      , "Products"."BrowseNodeId"
FROM "Products"
ORDER BY random()
LIMIT 100

答案 1 :(得分:0)

这是一个适用于我的用例的解决方案(为网页选择100个随机产品):

  1. 复制表格
  2. 随机播放表行
  3. 添加自动增量列
  4. 从随机范围中选择(例如100-200,1567000-1567100)
  5. 查询时间在 2ms 下降。

    以下是我使用的一组命令:

    create table RandProducts as select * from "Products" order by random();
    alter table RandProducts add column RandId serial8;
    create index on RandProducts(randid);
    

    然后要获得100个随机行,我就是这样做的:

    select * from Products where RandId between 8000 and 8100;