случайные данные с использованием php и mysql - PullRequest
0 голосов
/ 20 апреля 2010

У меня есть структура базы данных mysql, как показано ниже:

CREATE TABLE test (
    id int(11) NOT NULL auto_increment,
    title text NULL,
    tags text NULL,
    PRIMARY KEY (id)
);

данные о тегах полей хранятся в виде текста через запятую, такого как html, php, mysql, веб-сайт, html и т. Д. Теперь мне нужно создать массив, который содержит около 50 случайно выбранных тегов из случайных записей.

В настоящее время я использую rand (), чтобы выбрать 15 случайных данных mysql из базы данных, а затем храню все теги из 15 записей в массиве. Затем я использую array_rand () для рандомизации массива и выбора только 50 случайных тегов.

$query=mysql_query("select * from test order by id asc, RAND() limit 15");
$tags="";
while ($eachData=mysql_fetch_array($query)) {
    $additionalTags=$eachData['tags'];
    if ($tags=="") {
        $tags.=$additionalTags;
    } else {
        $tags.=$tags.",".$additionalTags;
    }
}

$tags=explode(",", $tags);
$newTags=array();
foreach ($tags as $tag) {
    $tag=trim($tag);
    if ($tag!="") {
        if (!in_array($tag, $newTags)) {
            $newTags[]=$tag;
        }
    }
}

$random_newTags=array_rand($newTags, 50);

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

Ответы [ 3 ]

3 голосов
/ 20 апреля 2010

Никогда ORDER BY RAND() - это ужасно для производительности. Вместо этого сделайте рандомизацию в PHP. Примерно так, поскольку ваш идентификатор автоматически увеличивается (возможно, это не лучший подход):

$count = mysql_fetch_assoc(mysql_query("select count(1) as count from test"));
$range = range(0, $count['count']);

$selection = array_rand($range, 50);
$sel_list = implode(',', $selection);

$query = mysql_query("select * from test where id in ($sel_list)");

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

0 голосов
/ 20 апреля 2010

Процедура Маркуса может быть улучшена, например

SELECT * FROM test
WHERE id % round(rand()*(SELECT count(*) FROM test)) = 0
ORDER BY id
LIMIT 15

(и это не слишком медленно). Единственная проблема в том, что вышеприведенное выражение не гарантирует, что вы получите 15 записей. Хотите что-нибудь подобное? Это может быть улучшено, чтобы гарантировать 15 записей.

0 голосов
/ 20 апреля 2010

Я думаю, вы, наверное, знаете, почему ORDER BY RAND() медленный. Запрос читает все записи, затем упорядочивает их без помощи индекса.

Если вы выберете случайное число между 0 и MAX(id) - 15 и получите следующие 15 строк, будет ли оно достаточно случайным? Записи введены неупорядоченно?

SELECT * FROM test
WHERE id >= my_random_value
ORDER BY id
LIMIT 15
...