比如在0-100中隨機取三個數,不重復(不能使用隨機取一個,再隨機取第二個判斷是否重復,重復則重新取這種套環的方法)
uj5u.com熱心網友回復:
現在我的想法是創建一個100條資料的臨時表,然后order by rand() limit 3,覺得太繁瑣uj5u.com熱心網友回復:
SELECT CEIL(RAND() * (100)) from temp_table order by rand() limit 3;
uj5u.com熱心網友回復:
order by rand()取隨機訊息原理1:創建臨時表用memory引擎,有兩個欄位分別是double型別欄位R和需要取出的欄位,且沒有索引
2:用rand()為每一行生成一個0到1的亂數,存入double的欄位R中
3:按照R欄位排序:初始化sort_buffer,將記憶體臨時表一行一行取出R欄位和位置資訊(每個引擎用來唯一標識資料行的資訊,對于有主鍵的表這個rowid就是主鍵id,沒有主鍵的就由系統生成一個rowid,對于memory引擎rowid就是陣列的下標)放入sort_buffer中,按R欄位排序。
4:排序完成后,取出limit 10行回傳給客戶端。
tmp_table_size限制了記憶體臨時表的大小,默認值是16M。如果臨時表大小超過了這個值記憶體臨時表就會轉成磁盤臨時表。
mysql 5.6引入新排序演算法,即優先佇列排序演算法,臨時檔案的演算法是歸并排序演算法.
read_buffer_size和read_rnd_buffer_size:這兩個都是按session獨占的,增大read_rnd_buffer_size和max_length_for_sort_data可以改善order by sql性能。
Max_length_for_sort_data大小決哪種(共兩種)排序演算法,超過此值會使用磁盤臨時檔案排序
Max_sort_length變數可以指定當用blob或text前綴排序時,這個前綴有多大
Sort_buffer_size默認是全域的,一旦排序mysql會立刻分配指定大小記憶體不管是否需要這么大,可以查詢前增加,如下所示
set @@session.sort_buffer_size :=409600
#執行陳述句
Set @@session.sort_buffer_size :=default
MySQL支持兩種方式的排序filesort和index,Using index是指MySQL掃描索引本身完成排序。index效率高,filesort效率低。
② order by滿足兩種情況會使用Using index:
a. order by陳述句使用索引最左前列。
b. 使用where子句與order by子句條件列組合滿足索引最左前列。
③ 盡量在索引列上完成排序,遵循索引建立(索引創建的順序)時的最佳左前綴原則。
④ 如果order by的條件不在索引列上,就會產生Using filesort。
⑤ group by與order by很類似,其實質是先排序后分組,遵照索引創建順序的最佳左前綴原則。注意where高于having,能寫在where中的限定條件就不要去having限定了。
using FileSort優化有兩種排序演算法(摘自深入淺出mysql):
兩次掃描演算法:首先根據條件取出排序欄位和行指標資訊,之后在sourt_buffer中排序,如果sort_buffer不夠,則在臨時表temporary table中存盤排序結果,完成排序后,根據行指標回表讀取記錄。該演算法是mysql4.1之前采用的演算法。需要兩次訪問資料,第一次取排序欄位和行指標(顯示主鍵或是自動創建的隱式主鍵)資訊,第二次根據行指標回表獲取記錄(可能會導致大量隨機I/O操作),排序的時候記憶體開銷小
一次掃描演算法:一次性取出滿足條件的行所有欄位,然后在sourt_buffer中排序,真接輸出結果集。排序時候記憶體開鎖大,但是效率比兩次排序演算法要高。
mysql通過比較系統max_length_sort_data的大小和query陳述句取出欄位的總大小來判斷采用哪種演算法。如果此值更大,則使用一次掃描排序演算法,否則使用兩次掃描排序演算法。
Sort buffer都是面向客戶服務執行緒分配的,如果設定過大可能造成記憶體浪費。甚至導致記憶體交換。
uj5u.com熱心網友回復:
不需要建立臨時表,直接使用一個已經存在的表(select count(*) >= 3)就行
SELECT CEIL(RAND() * (100)) from temp_table order by rand() limit 3;
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/14991.html
標籤:MySQL
下一篇:能否徒勞地嘗試一下,呼叫Windows API,讓標準Treeview控制元件,正確顯示Unicode字符,而不是????
