2

以下查询在 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")

谢谢你!

4

2 回答 2

1

与您的查询相比,试试这个:

SELECT "Products"."Id"
      , "Products"."Title"
      , "Products"."ThumbHeight"
      , "Products"."LargeImageWidth"
      , "Products"."LargeImageHeight"
      , "Products"."Url"
      , "Products"."BrowseNodeId"
FROM "Products"
ORDER BY random()
LIMIT 100
于 2012-05-30T14:48:28.303 回答
0

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

  1. 复制表格
  2. 随机播放表格行
  3. 添加自动增量列
  4. 从随机范围中选择(例如 100-200、1567000-1567100)

查询时间下降到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;
于 2012-05-31T05:15:52.400 回答