2014-09-02 38 views
1

所以這裏是我的任務:從沒有主鍵的MySQL表中返回一個隨機行。快速搜索返回this page與此解決方案:從沒有主鍵的MySQL表中獲取一個隨機行 - 優化

SELECT column FROM table 
ORDER BY RAND() 
LIMIT 1; 

不幸的是,該解決方案不是最佳的,因爲this site明確。他們提出了以下修補程序,這是在PHP:

$offset_result = mysql_query(" SELECT FLOOR(RAND() * COUNT(*)) AS `offset` FROM `table` "); 
$offset_row = mysql_fetch_object($offset_result); 
$offset = $offset_row->offset; 
$result = mysql_query(" SELECT * FROM `table` LIMIT $offset, 1 "); 

足夠的,因爲我會在頁面上發佈這個好,但在此期間,我需要嘗試在原始的MySQL。所以我拳打在:

SELECT * 
FROM `table` 
LIMIT (SELECT FLOOR(RAND() * COUNT(*)) FROM `table`), 1; 

...並得到了以下錯誤:

#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 '(SELECT FLOOR(RAND() * COUNT(*)) FROM `table`), 1' at line 3 

但我不明白,因爲各個部件完美地工作。如果我輸入:

SELECT FLOOR(RAND() * COUNT(*)) 
FROM `table` 

...我得到0的隨機數達行減1的數量同樣,如果我輸入:

SELECT * 
FROM `table` 
LIMIT 2, 1 

...我得到的第三在表格中排(或第四行,如果我用3代替2等)

我在做什麼錯?提前致謝!

+0

來自http://dev.mysql.com/doc/refman/5.0/en/select.html - LIMIT帶有一個或兩個數字參數,它們都必須是非負整數常量(除了使用預準備語句時)。這表明你可以將'Floor(rand()* count(*))'讀入一個變量,然後用它來選取隨機行。 – Laurence 2014-09-02 22:43:28

+0

'mysql_query(「SELECT」。FLOOR(RAND()* COUNT(*))。「AS'offset' FROM'table'」)' – 2014-09-02 22:43:55

+0

您可以使用存儲過程來保存RAND()* COUNT但是您可能更適合在網絡應用程序中保存行的總數,具體取決於更新的頻率。另外,根據您所談論的行數,原始非優化解決方案可能足夠快。 – ldg 2014-09-02 23:19:29

回答

0

如果你想要一個隨機抽樣,下面可能是速度不夠快:

SELECT * 
FROM `table` t cross join 
    (select count(*) as cnt from table t) const 
WHERE rand() <= 100/cnt 
ORDER BY rand() 
LIMIT 1 ; 

這確實有掃描表,但排序是在大約100行,這應該是足夠快。