Итак, у меня довольно большой запрос, который искал хотя пользователи 6k и сайты 3k, которые используют это, чтобы быть хорошими при запуске сайта, но теперь сайт становится огромным, страница, которая выполняет этот запрос, начала отставать, просто ища предложения о том, как я мог бы ускорить это до
$stmt212 = $db->prepare('SELECT *
FROM websites w
LEFT JOIN users u ON u.username = w.owner
WHERE u.coins >= ?
ORDER BY RAND()
LIMIT 1');
$stmt212->execute( array('1') ) ;
$row212 = $stmt212->fetch();
У пользователей есть «монеты» на моем веб-сайте, и предметы, которые они зарабатывают, а затем они просматриваются, так что я делаю выше, захватывая пользователя, у которого монет больше 1 и у кого есть предмет.
Вам нужно будет сделать с двумя запросами вместо одного.
Получить количество записей, соответствующих вашим критериям
$stmt212count = $db->prepare("SELECT
count(*)
FROM
websites w
INNER JOIN
users u ON
u.username = w.owner
AND u.coins >= :coins
");
$stmt212count->bindValue('coins', 1, PDO::PARAM_INT);
$stmt212count->execute();
$row212count = $stmt212count->fetch(PDO::FETCH_COLUMN);
Выберите случайный ряд
# random row offset
$offset = rand(0, $row212count-1);
используйте это утверждение, если у вас эмуляция PDO готовится включить
$stmt212 = $db->prepare(sprintf(
"SELECT
*
FROM
websites w
INNER JOIN
users u ON
u.username = w.owner
AND u.coins >= :coins
LIMIT %d,1
",
$offset
);
$stmt212count->bindValue('offset', $offset, PDO::PARAM_INT);
используйте это, если вы не используете эмуляцию PDO
$stmt212 = $db->prepare("SELECT
*
FROM
websites w
INNER JOIN
users u ON
u.username = w.owner
AND u.coins >= :coins
LIMIT :offset,1
");
используйте это для обоих утверждений
$stmt212count->bindValue('coins', 1, PDO::PARAM_INT);
$stmt212count->execute();
$row212 = $stmt212->fetch();
Как указано в большинстве комментариев, используя RAND()
в запросе Можно быть плохой вещью Я предполагаю, что оба столбца не проиндексированы, что делает драйвер базы данных очень сложным.
Чтобы сохранить структуру вашей базы данных и поддерживать производительность, вы можете позволить PHP рандомизировать ваши индексы для вас:
$stmt = $db->prepare('
SELECT *
FROM websites w
LEFT JOIN users u ON u.username = w.owner
WHERE u.coins >= ?
');
$stmt->execute(array('1')); // why are you not checking if this succeeds?
$result = $stmt->fetchAll(PDO::FETCH_NUM);
$result = array_rand($result);
print_r($result);