簡體   English   中英

當在SELECT語句中使用RAND()時,為什么MySQL返回相同的結果?

[英]Why is MySQL returning the same results while using RAND() in the SELECT statement?

我打開了許多瀏覽器窗口,它們指向相同的自動刷新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>

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返回相同的結果集。

不太確定,但是由於您的查詢中沒有LIMIT,所以我認為從查詢中刪除速度非常慢的ORDER BY RAND()部分並在mysql查詢結果中使用php函數shuffle可能是個好主意。

您並沒有限制記錄的數量,因此,他只會帶來不同的訂單,但是在您所在的位置卻獲得相同的結果。 嘗試限制您的結果

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

在某些結果集中,您可能正在從MySQL查詢緩存中接收信息。

嘗試這個:

SELECT SQL_NO_CACHE *
       /* etc */

注意:將SQL_NO_CACHE詞與SELECT和*(或您選擇的第一列的名稱)放在同一行。

參見: http : //dev.mysql.com/doc/refman/5.1/en/query-cache.html它說,

查詢緩存將SELECT語句的文本與發送到客戶端的相應結果一起存儲。 如果以后收到相同的語句,則服務器從查詢緩存中檢索結果,而不是再次解析並執行該語句。 查詢緩存在會話之間共享,因此可以響應另一個客戶端發出的同一查詢來發送一個客戶端生成的結果集。

專家提示:避免在軟件中使用SELECT * 提供結果集中所需的列的名稱。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM