postgresql выборка 100 случайных строк



Следующий запрос занимает около 300-400 МС на postgresql 9.1.
Таблица содержит ~2М строк.
Оправдано ли такое исполнение? Можно ли его улучшить?



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")



Спасибо!

682   2  

2 ответов:

Попробуйте сделать это в сравнении с вашим запросом:

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

Вот решение, которое хорошо работает для моего случая использования (выберите 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;

Comments

    Ничего не найдено.