我打开了许多浏览器窗口,指向同一个自动刷新的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>
答案 0 :(得分:2)
当没有第二个值时,MySQL使用系统时钟播种RAND()
。种子值以微秒为单位,我无法重现RAND()
生成相同值两次的问题。
如果您打开MySQL Workbench并同时执行两个语句。每个输出都不同。
SELECT RAND();
SELECT RAND();
当您打开多个标签并获得相同的结果时。这可能是一个缓存问题,但是您声明要标记URL以防止缓存。因此,在服务器上启用SQL日志记录并验证是否正在调用新查询。
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返回相同的结果集。
答案 1 :(得分:1)
不太确定,但由于你的查询中没有LIMIT,我认为从查询中删除那个非常慢的ORDER BY RAND()部分并简单地在结果上使用php函数shuffle是个好主意mysql查询。
答案 2 :(得分:1)
你并没有限制记录的数量,因此他只会带来不同的订单,但是同样的结果会出现在你的位置。尝试限制结果
$query = "SELECT * FROM customers WHERE customer_group='consumables' AND customer_updated < DATE_SUB(NOW(), INTERVAL 1 DAY) ORDER BY RAND() LIMIT 10";
答案 3 :(得分:1)
您可能正在某些结果集中从MySQL查询缓存中接收信息。
试试这个:
SELECT SQL_NO_CACHE *
/* etc */
注意:将SQL_NO_CACHE字放在与SELECT和*(或您选择的第一列的名称)相同的行上。
请参阅:http://dev.mysql.com/doc/refman/5.1/en/query-cache.html它说,
查询缓存存储SELECT语句的文本 发送给客户端的相应结果。如果相同 稍后收到语句,服务器从中检索结果 查询缓存而不是再次解析和执行语句。该 查询缓存在会话之间共享,因此一个结果集生成 可以发送客户端以响应另一个发出的相同查询 客户端。
专业提示:在软件中避免使用SELECT *
。在结果集中提供所需列的名称。