Альтернатива использованию порядка по rand ()? - PullRequest
0 голосов
/ 02 марта 2019

В настоящее время у меня есть запрос, используя order by rand (), чтобы получить 1000 разных строк, а не приращение.

Любая идея, как оптимизировать этот запрос, который возвращает 1000 случайных результатов, а не приращение, например, это:

select * 
 from table1 
 where not exists
        ( select id 
            from table2 
           where id = table1.id) 
   and prize_list_id = 100 
   and prize_group_id  in (109,111,113,119,120,127,129) 
 order 
    by rand() limit 1000;

1 Ответ

0 голосов
/ 02 марта 2019

Предположительно, вы не знаете, сколько строк будет возвращено, поэтому необходимо рассчитать.

Идея состоит в следующем:

  • Рассчитать количество строквозвращается.
  • Используйте rand() в предложении WHERE, чтобы свести множество к разумному числу.
  • Используйте order by rand() для окончательной случайности.

Это выглядит следующим образом:

select t.*
from (select t1.*, (@cnt := @cnt + 1) as seqnum,
             rand() as rnd
      from table1 t1 cross join
           (select @cnt := 0) params
      where not exists (select id 
                        from table2 
                        where id = table1.id
                       ) and
            prize_list_id = 100 and
            prize_group_id in (109, 111, 113, 119, 120, 127, 129) 
     ) t
where rnd < 2000 / @cnt
order by rnd
limit 1000

where должен выбрать где-то около 2000 строк, что является безопасным числом, чтобы быть уверенным, что у вас есть по крайней мере 1000 (на самом деле, вы, вероятно, можете использовать меньшее числокак 1200).order by тогда находится в меньшем подмножестве и должен быть быстрее.

Я не думаю, что rand() является особенно дорогой функцией, но это предварительно вычисляет значение для каждой строки, так что это тольковызывается один раз для каждой строки в подзапросе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...