так посоветуйте на указанных выше примерах, как переделать запросы
Информации в интернете достаточно чтобы выбрать один из способов. Можно и свой придумать.)
Но раз Вам так интересно — давайте проведем небольшой эксперимент.
Говорю сразу что тесты не претендуют на точность.
Характеристики машины
Ocь: Ubuntu 13.04 64bit
Проц: Intel® Core™ i5-3570K CPU @ 3.40GHz × 4
Память: 8 G
Часть 1. Подготовка данных.
Создадим тестовых пользователей. Думаю хватит
один-два миллиона.
Потом что-то мне надоело ждать — прервал работу скрипта. Получилось
1,672,354 юзеров.
$inDB = cmsDatabase::getInstance();
for ($i = 1; $i < 2000000; $i++) {
'nickname' => "user_{$i}",
"login" => "user_{$i}",
);
$inDB->insert('cms_users', $item);
}
Часть 2. Логика.
Я просо хочу проверить теорию — что 10 запросов к базе данных отработают быстрее чем
один запрос с ORDER BY RAND().
Кодим...
class RandomUser {
private $db;
private $limit;
private $usersTableName = 'cms_users';
private $users = array();
public function __construct($limit) {
$this->db = cmsDatabase::getInstance();
$this->limit = $limit;
}
public function getUsers() {
$maxId = $this->getMaxId();
for ($i = 0; $i < $this->limit; $i++) {
// получаем рандомный Id
// составляем sql запрос
$sql = "SELECT id, nickname FROM {$this->usersTableName} AS u WHERE id >= {$randomId}";
// одного пользователя можно достать только 1 раз
$sql .= $usersIds ?
' AND id NOT IN (' . implode(',', $usersIds) . ')' : ''; $sql .= " ORDER BY id ASC LIMIT 1";
$user = $this->db->query($sql)->fetch_object();
$usersIds[] = $user->id;
$this->users[] = $user;
}
return $this->users;
}
public function getUsersBadMethod() {
$sql = "SELECT id, nickname FROM {$this->usersTableName} ORDER BY RAND() LIMIT {$this->limit}";
$result = $this->db->query($sql);
while($user = $this->db->fetch_assoc($result)) {
$this->users[] = $user;
}
return $this->users;
}
/**
* @return int - максимальный (последний) Id пользователя
*/
private function getMaxId() {
$sql = "SELECT MAX(id) as maxId FROM {$this->usersTableName}";
return $this->db->query($sql)->fetch_object()->maxId;
}
}
И еще один класс.
Хелпер для подсчета времени выполнения скрипта.
class Timer {
private $startTime;
private function getTime() {
return ((float) $usec + (float) $seconds);
}
function start() {
$this->startTime = $this->getTime();
}
return ($this->getTime() - $this->startTime);
}
}
Ну вот и все. Работаем...
$timer = new Timer();
$timer->start();
$randomUser = new RandomUser(10);
$users = $randomUser->getUsers();
$timer->start();
$randomUser = new RandomUser(10);
$users = $randomUser->getUsersBadMethod();
echo '<br />';
Time 1 — десять запросов
Time 2 — один не очень хороший (имхо) запрос
Time 1: 0.0030 sec
Time 2: 2.4021 sec
Time 1: 0.0026 sec
Time 2: 2.6235 sec
и т.д.