Выбрать случайным образом поле из БД

SiMM

Новичок
> вообще не понял, что неправильно-то?
Правильно, неправильно - эти два слова тут не при чём. Выше было сказано
> если таблица очень большая
и ты считаешь, что выбрать все id из базы (суммарный объём полученной инфы, я так понимаю, может быть довольно большим), а потом выбрать конкретный id, будет быстрее, чем взять количество записей в базе и затем выбрать случайную?
Ну что ж... последуй совету Фаната
PS: кстати, нормальный (ИМХО) вариант в два запроса в форуме приводился, и не раз, только что-то с поиском стало туго - найти не смог - в двух словах - узнаёшь число записей, а потом делаешь выборку с LIMIT $rand,1, где $rand - число от 0 до количества записей-1.
 

Фанат

oncle terrible
Команда форума
SiMM лимит тоже тормозит при большом первом операторе.
 
Я даже позволю по теоретизировать, и сказать, что зва запроса:
1а.select id from table
1б.select * from table where id=$id
будут выполняться быстрее чем
2а.select count(*) from table
2б.select * from table limit $rand,1
Поскольку 1.а и 2.б - практически идентичны по операциям.

Правда, это если не учитывать, что между ними есть еще и PHP-код.
 

SiMM

Новичок
> SiMM лимит тоже тормозит при большом первом операторе.
Ну так ждём результатов :)
 

Demiurg

Guest
>Поскольку 1.а и 2.б - практически идентичны по операциям.
особенно если записей несколько миллионов, то всего то придется несколько мегабайт потаскать туда-сюда ради одной записи.
 

Demiurg

Guest
Дмитрий Попов
ну ты утверждаешь, что запроса 1а и 1б будут быстрее, значит тебе
 

Demiurg

Guest
а причем тут php код ?
select id from table
подразумевает передачу кучи данных от сервера клиенту, что само по себе является большим тормозом.
 
Да согласен, но я как раз имел ввиду нагрузку на сервер - хотя ужасно выразил свою мысль.

Короче - не то. В любом случае оба запроса с точки зрения нагрузки плохи.
 

berkut

Новичок
ну вот я попробывал провести тест, самое интересное - в первом и втором тестах загрузка цп колебаласьь в районе 75%,а в третьих тестах всё время в районе 5%, редкие пики не превышали 15%
Код:
1) SELECT id FROM test_tbl
$id = mysql_result($res, rand(0, mysql_num_rows($res) - 1), 'id');
SELECT * FROM test_tbl WHERE id = '.$id

2)SELECT COUNT(*) FROM test_tbl
$rand = rand(0, $row[0] - 1);
SELECT * FROM test_tbl LIMIT $rand, 1

3)SELECT * FROM test_tbl  ORDER BY rand() LIMIT 1
----------------------------------

table 50000 rows, 200 iterations:
1)
max: 0.34210395813
min: 0.282004117966
aver: 0.292976770401

2)
max: 0.0803759098053
min: 0.00165700912476
aver: 0.0374244022369

3)
max: 1.39973902702
min: 0.399183034897
aver: 0.857018735409
*******************

table 500000 rows, 100 iterations:
1)
max: 3.21578407288
min: 2.78701806068
aver: 2.85369098186

2)
max: 11.5205681324
min: 0.00355005264282
aver: 0.428873405457

3)
36.2902951241
55.6815538406
39.872710228
35.1975901127
38.1544430256
33.8442900181
34.6137750149
47.4763100147
45.4094619751
31.2708039284
27.9109771252
30.035243988
27.8086028099
27.8297629356
27.668847084
28.2180171013
Fatal error: Maximum execution time of 600 seconds exceeded in ...
***********************************************

table 10 rows, 100 iterations:

1)
max: 0.0116949081421
min: 0.00061297416687
aver: 0.000861039161682

2)
max: 0.00726795196533
min: 0.0013427734375
aver: 0.00162561893463

3)
max: 0.479746818542
min: 0.336087942123
aver: 0.358664484024
вот код тестирования
PHP:
set_time_limit(600);

function getMicrotime() {
    list($usec, $sec) = explode(' ', microtime());
    return ((float)$usec + (float)$sec);
}

mysql_connect('localhost', 'root', '');
mysql_select_db('cat');
$test_num = 3;  // выбираем номер теста 
for ($i = 0; $i < 100; $i++) {
    $start_time = getMicrotime();

    if ($test_num == 1) {
        $sql1 = 'SELECT id FROM test_tbl';
        $res = mysql_query($sql1);
        $id = mysql_result($res, rand(0, mysql_num_rows($res) - 1), 'id');
        mysql_free_result($res);
        $res2 = mysql_query('SELECT * FROM test_tbl WHERE id = '.$id);
    }
    elseif ($test_num == 2) {
        $sql1 = 'SELECT COUNT(*) FROM test_tbl';
        $res = mysql_query($sql1);
        $row = mysql_fetch_row($res);
        $rand = rand(0, $row[0] - 1);
        $sql = "SELECT * FROM test_tbl LIMIT $rand, 1";
        $res2 = mysql_query($sql);
    }
    elseif ($test_num == 3) {
        $sql1 = "SELECT * FROM test_tbl  ORDER BY rand() LIMIT 1";
        $res = mysql_query($sql1);
    }

    $stop_time = getMicrotime();
    $exec_time = $stop_time - $start_time;

    echo $exec_time."<br>\r\n";
    $exec_res[] = $exec_time;
}

echo '<h1>max: '.max($exec_res).'<br>';
echo '<h1>min: '.min($exec_res).'<br>';
echo '<h1>aver: '.(array_sum($exec_res) / sizeof($exec_res)).'<br>';
а это таблица и как заполнялась:
Код:
CREATE TABLE `test_tbl` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`col1` VARCHAR( 255 ) NOT NULL ,
`col2` VARCHAR( 255 ) NOT NULL ,
`col3` INT( 2 ) NOT NULL
);
PHP:
for ($i = 0; $i < 50000; $i++) {
        $str1 = str_repeat('long test string', rand(0, 120));
        $str2 = str_repeat('aNoTHer test string', rand(0, 120));
        $sql = "INSERT INTO test_tbl VALUES (null, '$str1', '$str2', $i)";
        mysql_query($sql) or print(mysql_error().'<br>');
}
 

BeatBox

Guest
вы меня запутали и напугали я так и непонял как мне делать :)
 
Сверху