2013-01-05 28 views
0

有包含這樣的表:MySQL的:快速選擇n的表隨機行,其中一對列(不是列)都是獨一無二的

ID,爲person_id,pet_id介紹

有是關於該表的一些聲明:

  1. ID是主鍵,自動增量
  2. 每對(爲person_id,pet_id)是獨特
  3. ID,爲person_id,pet_id是整數,NOT NULL
  4. 「洞」是可能的(最大pet_id並沒有告訴我們總共有(最多)等爲person_id列數)
  5. 這是非常有可能的表格中的person_id更加不同,即每個人的pet_id的平均數量。

問題是:如何快速選擇當前person_id的隨機N pet_id?表

例子:

1. 1 1  cat 
2. 1 2  dog 
3. 2 40 horse 
4. 2 35 dog 
5. 3 46 duck 
6. 2 39 duck 
7. 1 3  duck 
.................. 
100000 403 12 monkey 

例子:我要選擇的那個人二號兩個隨機行。可能的隨機選擇之一是#3行。和第6行。 選擇應該是真正的「隨機」(應該以相同的概率出現)。

如何使用MySQL查詢選擇做呢?

P.S.當然,我已經閱讀了關於從表中選擇幾個隨機行的問題,這是一些棘手的解決方案的基本問題。但是,在我的情況下,有兩排,而不是一排。

我想更快的方法比

select id from tablename where person_id = 2 order by random() limit 2; 

回答

1

您的strawman查詢與您所能做的一樣好。如果你沒有一個有很多寵物的人(並且你有一個person_id索引),它應該運行得很快。如果你確實有這樣一個人,那麼你的運氣不好。忘記隨機選擇,甚至要確定這樣一個人有多少寵物需要時間O(#寵物)。

其中一個可能不會爲你工作,可能其他的想法:如果你不關心你的選擇(例如,你可能每次都得到相同的隨機響應)的獨立性,那麼你可以添加一列其中在插入行時填充一個隨機數。在person_id,random_column上添加一個索引,然後選擇由該對排序的前N行。稍好一點的是添加多個隨機列,並選擇一個隨機排序。不幸的是,這不能很好地擴展,我不認爲你會對結果感到滿意。

+0

謝謝。想法很好的想法,嘗試甚至嘗試擴展。我讀過兩遍。 我對不對? - 這張表被修改的越少(比如說,每週一次,管理員而不是用戶,他們只是使用它),更有意義的是添加列random_column1,...,random_column20並製作20個索引(person_id,random_column1 ),...,(爲person_id,random_column20)?因此,對於人類來說,行爲看起來會「非常隨機」,如果每秒鐘不會更改用戶表,那麼性能應該沒問題。我對嗎? – Haradzieniec

+1

是的,這聽起來不錯。如果這足夠隨機的話,就去做吧。 –

+0

非常感謝!你讓我很快樂。 – Haradzieniec

0

試試這個,在這裏我們減少數據庫隨機()函數執行的時間。

$max_sql = "SELECT max(id) AS max_id FROM " . $table; 
    $max_row = mysql_fetch_array(mysql_query($max_sql)); 
    $random_number = mt_rand(1, $max_row['max_id']); 

    $random_sql = "SELECT * FROM " . $table . " 
       WHERE " . $column . " >= " . $random_number . " 
       ORDER BY " . $column . " ASC 
       LIMIT 1"; 
+1

謝謝。不幸的是,就我所見,這種隨機行不會得到平等分配。讓我們來看看,如果pet_id 1,2,3,1000,10001對於第二個人存在差距,那麼對(person_id,pet_id)==(2,1000)將被選擇997次多於(2, 2)。另外,你必須在n次成功的時候迭代它(並且檢查你的$ random號碼不在所選的隨機數組中,並且這個查詢的分佈更平均)。 – Haradzieniec

相關問題