2012-08-26 43 views
2

我使用SQL優化來獲得隨機行

SELECT * 
    FROM picture 
INNER JOIN user ON picture.fbid = user.fbid 
WHERE hide = 0 
    AND userhide = 0 
ORDER BY gender, RAND() LIMIT 0 , 1 

此執行,給我的鏈接排隨機,其中性別是女性的照片。大約需要15秒鐘才能執行。

我怎麼可能更改SQL,使其計算快?我應該在Picture表中添加一個性別列,以便它不會同時包含這個表,然後獲取一個隨機行或者還有其他方法來優化SQL?

+0

爲什麼這個標籤'[MySQL的]'和'[SQL服務器]'?這是什麼,你有什麼指標,目前的解釋計劃是什麼? – Ben

+0

其MYSQL ..... – Yahoo

+2

順便說一句,有沒有保證返回行會有性別爲女......你需要用'和user.gender =「WHERE子句中female''。 – Ben

回答

3

[編輯]你可以做同樣的一個MySQL的存儲過程,我只是編碼在這裏:http://sqlfiddle.com/#!2/d0e6a/2

(注:由於沒有在每一查詢做會aliviate負載的數量,否則在此特殊情況下,它可以更慢,我會建議,讓您的查詢,但與指數優化或檢查了這一點:Is cross-table indexing possible?

[編輯2]這是一個使用的50000隨機的平均索引優化的另一個例子每個表中的條目:http://sqlfiddle.com/#!2/bfbe1/1查詢需要少於100毫秒(沒有索引我離開它運行幾分鐘,仍然沒有結果!)。您可以使用CREATE INDEX

這是一個使用2個查詢從PHP腳本我的解決方案建立在現有的表的索引:

$sql="SELECT COUNT(*) 
    FROM picture 
INNER JOIN user ON picture.fbid = user.fbid 
WHERE hide = 0 
    AND userhide = 0 
    AND gender = 'female' 
    GROUP BY gender"; 

$result=mysql_query($sql); 
$row=mysql_fetch_array($result); 

$sql="SELECT * 
     FROM picture 
     INNER JOIN user ON picture.fbid = user.fbid 
     WHERE hide = 0 
     AND userhide = 0 
     AND gender = 'female' 
     LIMIT FLOOR(RAND()*$row['COUNT(*)']),1"; 

$result=mysql_query($sql); 
$picture=mysql_fetch_array($result); 

這應該讓你查詢快了很多。

另外,如果你的表是很大的(我猜是這種情況,因爲查詢需要15秒),這將有助於如果有條件/連接字段建立索引。

+0

加入溶液作爲存儲過程,則可以避免發送多個查詢,檢查出來;) – NotGaeL

+0

SQL小提琴50000條記錄?爾加!這不是用於原始性能測試(因爲它受許多不同變量的影響);作爲測試用例,SQL小提琴應該可以幫助您製作查詢的結構。相對錶現可以通過比較執行計劃來判斷。我想我需要在MySQL數據庫大小設置硬限制,以防止這樣的事情 - 它太硬的服務器上,如果每個人都這樣說。 –

+0

你說得對,我會牢記這一點。無論如何,我還在我的筆記本電腦上使用virtualbox(1 GHz 1核心,1 GB RAM)進行了一些「實際」RAW測試,並獲得了均勻分佈的隨機記錄(每張桌上約有5000萬)。然後我發現'count(*)'query +'limit floor(rand()* count),1'在這種情況下查詢並不是最優化的:在這臺虛擬機上處理需要200到400秒之間,一個穩定的200以及'rand by(order by rand)'解決方案,我猜這取決於有多少記錄匹配查詢(在這種情況下,平均值爲3125000)。 – NotGaeL