Помогите оптимизировать sql выборку

VIN

Новичок
Всем доброго дня. Для выборки из таблицы случайной записи, набрасал код ниже. Есть 2 таблицы: table1 и table2. В table1 - множество str(записей), из неё, в зависимости от IP обратившегося, необходимо выводить случайную запись(str) лишь один раз. Т.е. одна и таже, для конкретного IP выводиться не должна! В table2 - сохраняются все ранее выведенные из table1 записи. Из неё выбираются все id'ы ранее выведенных для определённого IP и исключаются из sql условия. Код собственно работает. Но вот в оптимизации я не дальновиден. Всё ли на Ваш взгляд корректно? Спасибо за внимание =)

Код:
<?php
$cnnect = mysql_connect('localhost', 'root', 'PaSSwOD');
mysql_select_db('dbase');

$code = mysql_query("SELECT id FROM table2 WHERE IP='".$_SERVER["REMOTE_ADDR"]."'");
$id = array();

while($rows = mysql_fetch_row($code)){
$id[] = $rows[0];
}

if (!empty($id)){
$query = "SELECT id,str FROM table1 WHERE id NOT IN ( '" . implode($id, "', '") . "' ) ORDER BY RAND() LIMIT 1";
}
else
{
$query = 'SELECT id,str FROM table1 ORDER BY RAND() LIMIT 1';
}
$result = mysql_query($query);

if ($result) {
$per = mysql_fetch_array($result);
if (!empty($per['str'])) {
mysql_query("INSERT INTO table2 (id,ip,str,time) VALUES('".$per['id']."','".$_SERVER["REMOTE_ADDR"]."', '".$per['str']."', NOW());");
}

}

mysql_free_result($result);

mysql_close($cnnect);
?>
 

fixxxer

К.О.
Партнер клуба
У тебя есть колода карт. Чтобы взять случайную карту, ты каждый раз тасуешь колоду и потом берешь верхнюю карту. Вот и сам подумай, насколько это эффективно и как это зависит от размера колоды (особенно когда она перестанет помещаться в руках).
 
  • Like
Реакции: VIN

VIN

Новичок
У тебя есть колода карт. Чтобы взять случайную карту, ты каждый раз тасуешь колоду и потом берешь верхнюю карту. Вот и сам подумай, насколько это эффективно и как это зависит от размера колоды (особенно когда она перестанет помещаться в руках).
Меня тоже смущал сам механизм с RAND(). Поочерёдная выборка мне тоже не подходит. Нужен именно механизм случайного значения! Как бы вы решили поставленную задачу?
 
Последнее редактирование:

fixxxer

К.О.
Партнер клуба
Зависит от того, насколько равномерное распределение нужно.

Если допустимо, что записи, следующие сразу после "дырок" в PK, будут выбраны чаще, то достаточно where id >= случайное_значение_между_min_id_и_max_id order by id limit 1.
Если нет, то придется либо добавить искусственное поле без дырок (например, при создании записи максимум плюс один, а при удалении записи присваивать значение удаленнного максимальному), либо учитывать эти дырки при генерации случайного значения (как это эффективно сделать, не знаю).

Вообще это распространенная задача. Погугли.
 

VIN

Новичок
Зависит от того, насколько равномерное распределение нужно.

Если допустимо, что записи, следующие сразу после "дырок" в PK, будут выбраны чаще, то достаточно where id >= случайное_значение_между_min_id_и_max_id order by id limit 1.
Если нет, то придется либо добавить искусственное поле без дырок (например, при создании записи максимум плюс один, а при удалении записи присваивать значение удаленнного максимальному), либо учитывать эти дырки при генерации случайного значения (как это эффективно сделать, не знаю).

Вообще это распространенная задача. Погугли.
Спасибо. Буду копать в этом направлении!
 
Сверху