2012-09-15 41 views
4

我有16K項
的表我想提取隨機44項
但我不想重複同樣的條目,曾多次(曾經)
所以我有一個每個用戶列表,它將已經使用的'ID'作爲逗號分隔的字符串保存在表中。
我使用列表選擇... NOT IN(used_IDs)

的問題是,這個名單過於龐大和SQL調用失敗,因爲大小的,我相信
MYSQL隨機選擇唯一行 - 不包括先前選擇的行

任何想法如何要做得更有用嗎?

Questions table: 
+------+-------+-------+ 
| id | Qtext | Tags | 
+------+-------+-------+ 

Test table: 
+------+-------+ 
| id | QIDs | 
+------+-------+ 

Results table: 
+------+-------+-------+ 
| id | tID | uID | 
+------+-------+-------+ 

我需要根據結果表從問題表中選擇唯一的隨機值。 (該測試ID與問題ID相關聯)

目前嘗試使用:

SELECT DISTINCT `questions`.`ID` 
FROM `questions`, `tests`, `results` 
WHERE 
`questions`.`ID` NOT IN (`tests`.`qIDs`) 
AND `results`.`uID` = 1 AND `tests`.`ID` = `results`.`tID` 
AND 4 IN (`questions`.`tags`) 
AND "http://www.usmlestep2qna.com" = `provider` 
ORDER BY RAND() LIMIT 27; 

任何想法?

+0

16K的記錄是不是真的被大多數企業標準非常大的表。你可以分享查詢的表格結構和查詢計劃嗎?有可能在目前的做法本身.. – InSane

+0

上述編輯... – user1672888

+0

完成上述:) – user1672888

回答

1

而是在一列放置使用的用戶ID值在一個逗號分隔的字符串,你可以創建一個高大的表來存儲它們。這應該獲得更好的性能與

+0

我不確定爲每個用戶擁有16K行的表是否更好,然後將其存儲在一個字符串中 - 是嗎? – user1672888

+0

是的,因爲表可以被索引。 – Barmar

+0

你不需要每個用戶16K行。每次選擇ID時,只需向表中添加44行。 – Barmar

1

而不是使用單排與(潛在的巨大)CSV,爲什麼不使用索引很好的桌子和一個外連接接不匹配的記錄。我從我的測試數據庫中得到一個例子:

mysql> select * from first; 
+------+-------+ 
| id | title | 
+------+-------+ 
| 1 | aaaa | 
| 2 | bbbb | 
| 3 | cccc | 
| 4 | NULL | 
| 6 | gggg | 
+------+-------+ 
5 rows in set (0.00 sec) 

mysql> select * from second; 
+------+----------+------+------+-------+------+ 
| id | first_id | one | two | three | four | 
+------+----------+------+------+-------+------+ 
| 1 |  1 | 3 | 0 |  4 | 6 | 
| 1 |  2 | 4 | 4 |  1 | 2 | 
| 3 |  3 | 1 | NULL |  3 | 4 | 
+------+----------+------+------+-------+------+ 
3 rows in set (0.00 sec) 

mysql> select a.id from first a join second b on a.id=b.first_id; 
+------+ 
| id | 
+------+ 
| 1 | 
| 2 | 
| 3 | 
+------+ 
3 rows in set (0.00 sec) 

mysql> select a.id from first a 
left outer join second b on a.id=b.first_id where b.first_id is null; 
+------+ 
| id | 
+------+ 
| 4 | 
| 6 | 
+------+ 
2 rows in set (0.00 sec) 

這應該會很好地改善您的性能。