Методология случайного поиска - PullRequest
2 голосов
/ 01 июля 2011

У меня есть база данных postgres с таблицей, содержащей строки, которые я хочу просматривать с псевдослучайными интервалами. Некоторых я хочу посмотреть один раз в час, некоторых раз в день, а некоторых раз в неделю. Я хотел бы, чтобы поиски происходили с псевдослучайными интервалами внутри их временного окна. Итак, поиск, который я хочу сделать один раз в день, должен происходить в разное время при каждом запуске.

Я подозреваю, что есть более простой способ сделать это, но вот примерный план, который у меня есть: Есть столбец настроек для каждого элемента поиска. Когда скрипт запускается, он рандомизирует время эпохи для каждого поиска и устанавливает его в столбце настроек, определяя время для следующего поиска. Затем я запускаю непрерывный цикл с ожиданием 1, чтобы посмотреть, совпадает ли время эпохи с любым из запрошенных поисков. После запуска поиска, он пересчитывает, когда следующий поиск должен быть.

Мои вопросы: Даже на этапе проектирования это выглядит как рутина из клейкой ленты и шпагата. Какой правильный способ сделать это?

Если случайно моя идея - правильный способ сделать это, является ли моя идея повторить цикл с ожиданием 1 правильным путем? Если бы у меня было 2 поиска подряд, есть шанс, что я могу пропустить один, но я могу жить с этим.

Спасибо за вашу помощь!

Ответы [ 2 ]

5 голосов
/ 01 июля 2011

Добавить столбец в таблицу для NextCheckTime. Вы можете использовать либо метку времени, либо просто целое число с необработанным временем эпохи. Добавьте (неуникальный) индекс в NextCheckTime.

Когда вы добавляете строку в базу данных, заполняете NextCheckTime, беря текущее время, добавляя базовый интервал и добавляя / вычитая случайный множитель (может быть 25% от базового интервала или любой другой, соответствующий вашей ситуации). Например:

my $interval   = 3600; # 1 hour in seconds
my $next_check = time + int($interval * (0.75 + rand 0.5));

Тогда в вашем цикле, просто SELECT * FROM table ORDER BY NextCheckTime LIMIT 1. Затем спите до тех пор, пока NextCheckTime не вернется (при условии, что это еще не было в прошлом), выполните поиск и обновите NextCheckTime, как описано выше.

Если вам нужно обработать строки, недавно добавленные каким-либо другим процессом, вы можете наложить ограничение на режим сна. Если в будущем значение NextCheckTime превысит 10 минут, переведите в режим ожидания 10 минут и повторите SELECT, чтобы увидеть, были ли добавлены какие-либо новые строки. (Опять же, точный лимит зависит от вашей ситуации.)

0 голосов
/ 01 июля 2011

Насколько велик ваш набор данных?Если это несколько тысяч строк, тогда можно просто рандомизировать весь список и получить первые x строк.По мере роста размера вашего набора это становится все менее и менее масштабируемым.Производительность падает с нелинейной скоростью.Но если вам нужно запускать это не чаще одного раза в час, то нет ничего страшного, если это займет минуту или две, если это не убивает другие процессы в той же коробке.

Если у вас есть последовательность без промежутков, будь то с самого начала или добавленная, вы можете использовать индексы с чем-то вроде:

$i=random(0,sizeofset-1);
select * From table where seqid=$i;

и получить хорошую масштабируемость для миллионов и миллионов строк.

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