Почему MySQL возвращает те же результаты при использовании RAND () в инструкции SELECT?

У меня есть несколько открытых окон браузера, указывающих на ту же самую обновляющуюся страницу PHP. Он обращается к базе данных MySQL для идентификации устаревшей информации о клиентах. В частности, получение записей, которые не были обновлены в последний день и принудительно обновили. Остальная часть кода, похоже, отлично обрабатывается.

Вот мой запрос MySQLi:

$query = "SELECT * FROM customers WHERE customer_group='consumables' AND customer_updated < DATE_SUB(NOW(), INTERVAL 1 DAY) ORDER BY RAND() LIMIT 10"; 

Мне сообщили, что RAND () не очень подходит из-за медленной обработки больших таблиц, но мои таблицы не будут увеличиваться до более чем 20000 до конца этого проекта. У меня также есть случайная переменная, передаваемая по URL-адресу, например «clientdataupdates.php? Nocachepls = 1541231».

Итак, вот моя проблема: из текущих 5000 нечетных записей, если этот скрипт запускается в нескольких окнах обозревателя одновременно, они получают те же записи, что и MySQL. Разумеется, выбранная запись, по-видимому, выбирается случайным образом, но одна и та же запись возвращается во всех окнах, если запрос выполняется в одно и то же время.

Мои исследования были весьма ограничены тем фактом, что ключевые слова, которые я искал (в течение нескольких дней сейчас), по-видимому, относятся к другим проблемам, например: «php mysql возвращает тот же результат при использовании rand ()» имеет слишком много ответов Google, которые указывают к использованию rand () вообще.

Хотя я все равно буду признателен за любую помощь, я бы больше хотел узнать, почему это происходит. Мое знание внутренней работы MySQL ограничено, но для всего моего опыта взаимодействия с PHP и MySQL я не видел ничего подобного.

ОБНОВЛЕНО:

Я также проверил использование функции ajax, которая включает функцию обратного вызова, чтобы снова запустить ее. Каждый раз, когда содержимое div является одной и той же записью, но все равно выглядит, что выбранная запись произвольно.

 <div id='worker1' class='workerDiv'>worker: waiting..</div> <div id='worker2' class='workerDiv'>worker: waiting..</div> <div id='worker3' class='workerDiv'>worker: waiting..</div> <div id='worker4' class='workerDiv'>worker: waiting..</div> <div id='worker5' class='workerDiv'>worker: waiting..</div> <script> function nextWorker(thisWorker){ setTimeout(function(){ ajaxpage('customerdata_worker.php',thisWorker,nextWorker(thisWorker)); }, 10000); } setTimeout(nextWorker('worker1'), 100); setTimeout(nextWorker('worker2'), 100); setTimeout(nextWorker('worker3'), 100); setTimeout(nextWorker('worker4'), 100); setTimeout(nextWorker('worker5'), 100); </script> 

Вероятно, вы получаете информацию из кеша запросов MySQL в некоторых наборах результатов.

Попробуй это:

 SELECT SQL_NO_CACHE * /* etc */ 

ОСТОРОЖНО: Поместите слово SQL_NO_CACHE в ту же строку, что и SELECT, и * (или имя первого столбца, который вы выбираете).

Смотрите это: http://dev.mysql.com/doc/refman/5.1/ru/query-cache.html В нем говорится:

Кэш запросов хранит текст инструкции SELECT вместе с соответствующим результатом, который был отправлен клиенту. Если идентичный оператор получен позже, сервер извлекает результаты из кеша запросов, а не анализирует и выполняет оператор снова. Кэш запросов распределяется между сеансами, поэтому набор результатов, сгенерированный одним клиентом, может быть отправлен в ответ на тот же запрос, выданный другим клиентом.

Pro tip: Избегайте SELECT * в программном обеспечении. Укажите имена столбцов в наборе результатов.

Rand () семя

MySQL использует системные часы для семени RAND() когда нет второго значения. Начальное значение находится в микросекундах, и я не могу воспроизвести проблему RAND() производя одно и то же значение дважды, как вы описываете.

Если вы открываете MySQL Workbench и одновременно выполняете два оператора. Выход для каждого отличается.

 SELECT RAND(); SELECT RAND(); 

Когда вы открываете несколько вкладок и получаете одинаковые результаты. Вероятно, это проблема кэширования, но вы заявляете, что вы удаляете URL-адрес, чтобы предотвратить кеширование. Поэтому включите ведение журнала SQL на сервере и убедитесь, что вызываются новые запросы.

Rand () Производительность

ORDER BY RAND() медленный, потому что он требует, чтобы MySQL читал всю таблицу. Даже ORDER BY RAND() LIMIT 1 прежнему требует, чтобы MySQL читал всю таблицу.

ОБНОВИТЬ:

Вы можете увидеть, что такое случайное значение, которое генерирует SQL.

 $query = "SELECT *, RAND() AS `X` FROM customers WHERE customer_group='consumables' AND customer_updated < DATE_SUB(NOW(), INTERVAL 1 DAY) ORDER BY `X` LIMIT 10"; 

Это будет включать столбец X для каждой строки. Случайное значение, используемое для заказа запроса. Добавьте это к выходу и посмотрите, действительно ли каждый браузер возвращает одни и те же результирующие множества из MySQL.

Вы не ограничиваете количество записей, поэтому он только приносит разные заказы, но те же результаты, что и ваши места. Попробуйте ограничить свои результаты

 $query = "SELECT * FROM customers WHERE customer_group='consumables' AND customer_updated < DATE_SUB(NOW(), INTERVAL 1 DAY) ORDER BY RAND() LIMIT 10"; 

Не совсем уверен, но поскольку у вас нет LIMIT в вашем запросе, я думаю, что может быть хорошей идеей удалить эту очень медленную часть ORDER BY RAND () из вашего запроса и просто использовать shuffle функции php в результате запроса mysql.