2014-01-20 35 views
1

我有以下查詢ORDER BY RAND造成非常高負荷

$samecars = $this->QueryResult("SELECT * FROM carads where STATUS='1' and DEL='0' 
and TITLE !='' and IMAGE1 != '' and IMAGE1 != '-1' and PRICE BETWEEN $pricelow 
and $pricehigh order by RAND() LIMIT 0,3"); 

當我刪除RAND()查詢被執行幾乎是瞬間,如果我添加大約需要10-30秒RAND()

餐桌上有大約100萬行。 我需要RAND()才能使用隨機顯示。

更多細節:

QueryResult看起來像這樣

public function QueryResult($strQuery) { 
    $this->connector(); 
    $query = mysqli_query($this->link, $strQuery); 
    $arr = array(); 
    if ($query) { 
     while ($result = mysqli_fetch_object($query)) { 
      array_push($arr, $result); 
     } 
    } 
    $this->close(); 
    return $arr; 
} 

我也試過在SQL添加下面的示例命令

SELECT * FROM carads where STATUS='1' and DEL='0' 
and TITLE !='' and IMAGE1 != '' and IMAGE1 != '-1' and PRICE BETWEEN 8000 
and 15000 order by RAND() LIMIT 0,3" 

和RAND()被高亮紅,當我執行它通過#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '"' at line 3

+3

是的,它會的!..... –

+0

@MitchWheat我該如何克服這一點? – user3140607

+1

在你的sql中不需要最後的引號'「' –

回答

3

1.俄羅斯輪盤賭採樣

爲什麼RAND()導致問題的原因是因爲該表中的所有行查詢,而不是例如前三。此外,排序需要一些時間。

一個想法,以加快處理是使用俄羅斯輪盤賭採樣:

SELECT * FROM carads where STATUS='1' and DEL='0' and TITLE !='' and IMAGE1 != '' and IMAGE1 != '-1' and PRICE BETWEEN $pricelow and $pricehigh AND RAND() < 0.001 LIMIT 0,3 

其中0.001是相當小的。這種方法的問題是不會統一挑選物品(第一個物品有更多機會)。此外,概率應取決於表格的大小(因此偶爾,管理工具應重新計算概率)。然而,這是解決問題的實用解決方案。

2. PHP所從事的工作(大多數)

因爲只有三行,您可以執行以下步驟:

  1. 首先查詢數據庫中查找的行數
  2. 生成0和行數之間的三個不同的隨機數(獨佔)
  3. 查詢三行並處理數據。
+0

我加了0.01,現在它處理它在從45秒0.03秒。他們是隨機的,10次刷新,從來沒有遇到過同樣的車。 – user3140607

+0

「10次刷新,從未遇到過同樣的車」 - 幾乎不是統一性的明確測試! –

+0

正如我在答案中所聲稱的那樣,這些項目確實不統一:第一個元素比上一個元素有更多機會被挑選。然而在工程中,存在着「痛苦的保存」的規律。有時候需要犧牲一些質量來使其可行。 –

0

查詢執行速度慢的另一個原因是,當使用像rand(),時間函數等聚合函數...阻止查詢被緩存。因此,一個好的做法是儘量不要在SQL查詢中使用這些類型的功能,並通過它與PHP,如:中

$query = "SELECT * FROM table order by " . rand(); 

代替

$query = "SELECT * FROM table order by RAND()"; 

希望它是有用的。

Regards

+0

我不明白這可能如何工作。結果查詢變成例如'SELECT * FROM table order by 0.75165156'。這意味着所有行都具有相同的order-attribute。因此,SQL可能會產生原始順序(或至少是確定性的順序)。 –