搜尋
首頁資料庫mysql教程MySQL中的隨機抽取如何實現

MySQL中的隨機抽取如何實現

Jun 03, 2023 am 08:25 AM
mysql

1. 引言

現在有一個需求是從一個單字表每次隨機選取三個單字。

這個表的建表語句和如下所示:

mysql> Create table 'words'(
    'id' int(11) not null auto_increment;
    'word' varchar(64) default null;
    primary key ('id')
) ENGINE=InnoDB;

然後我們向其中插入10000行資料。接下來我們來看看如何從中隨機選出3個單字。

2. 記憶體臨時表

首先,我們通常會想到用order by rand()來實作這個邏輯:

mysql> select word from words order by rand() limit 3;

雖然這句話很簡單,但執行流程則比較複雜。我們使用explain來看看語句的執行情況:

MySQL中的隨機抽取如何實現

Extra欄位中Using temporary表示需要使用臨時表,Using filesort表示需要進行排序。也就是需要進行排序操作。

對於InnoDB表來說,執行全字段排序能夠減少對於磁碟的訪問,所以會被優先選擇。

MySQL中的隨機抽取如何實現

而對於記憶體表來說,回表過程只是簡單地根據資料行的位置,直接存取記憶體得到數據,根本不會導致多存取磁碟。所以這時MySQL會優選選擇rowid排序。

MySQL中的隨機抽取如何實現

我們接下來再來梳理下這條語句的執行流程:

  • 建立一個臨時表,這個表使用memory引擎,表裡有兩個字段,第一個字段是double類型,記為R,第二個字段是varchar(64)類型,記為W。而這個表沒有索引。

  • 從words表中,按主鍵順序取出所有的word。對於每個word,呼叫rand()函數隨機產生一個大於0小於1的隨機小數,並將這個隨機小數和word分別存入臨時表的R和W欄位。

  • 接下來就是依照欄位R進行排序

  • 初始化sort_buffer。 sort_buffer包括一個double類型和一個整數欄位。

  • 從記憶體臨時表中一行行取出R值和位置信息,分別存入sort_buffer的兩個欄位裡。

  • sort_buffer依照R值進行排序

  • #排序完成後,取出前三個結果的位置信息,到記憶體臨時表中取出相應的word,回傳給客戶端。

流程示意圖如下所示:

MySQL中的隨機抽取如何實現

#上面講的位置信息,其實就是行所在的位置,也就是我們之前說的rowid。

#對於InnoDB引擎來說,對於有沒有主鍵表來說有兩種處理方式:

  • 對於有主鍵的InnoDB表來說,這個rowid就是主鍵id

  • 對於沒有主鍵的InnoDB表來說,這個rowid是由系統產生的,用來識別不同行。

因此,order by randn()使用了記憶體臨時表,記憶體臨時表的排序方法用的是rowid排序方法

3. 磁碟臨時表

不是所有的臨時表都是記憶體臨時表。 tmp_table_size這個配置限制了記憶體臨時表的大小,如果超過了這個大小,就會使用磁碟臨時表。 InnoDB引擎就是預設使用磁碟暫存表

4. 優先隊列排序演算法

在MySQL5.6之後,引入了優先隊列排序演算法,這種演算法是不需要使用臨時檔案的。而原本的歸併排序演算法則是需要使用臨時檔案。

因為當你使用歸併演算法的時候,其實你只需要得到前3,但是你是用完歸併排序,那已經整體有序了,造成了資源的浪費。

而優先佇列排序演算法則可以只取到前三,執行流程如下:

  • 對於這10000個準備排序的(R,rowid),先取前三行,建構成一個堆,並且將最大的值放在堆頂;

  • 取下一行(R’,rowid’),跟當前堆裡面最大的R比較,如果R’小於R,則把(R,rowid)從堆中去掉,換成(R’,rowid’)。

  • 不斷重複上面的過程。

流程如下圖所示:

MySQL中的隨機抽取如何實現

#但是當limit的數比較大時,維護堆比較困難,所以又會使用歸併排序演算法。

以上是MySQL中的隨機抽取如何實現的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:亿速云。如有侵權,請聯絡admin@php.cn刪除
mysql:blob和其他無-SQL存儲,有什麼區別?mysql:blob和其他無-SQL存儲,有什麼區別?May 13, 2025 am 12:14 AM

mysql'sblobissuitableForStoringBinaryDataWithInareLationalDatabase,而ilenosqloptionslikemongodb,redis和calablesolutionsolutionsolutionsoluntionsoluntionsolundortionsolunsonstructureddata.blobobobissimplobisslowdeperformberbutslowderformandperformancewithlararengedata;

mySQL添加用戶:語法,選項和安全性最佳實踐mySQL添加用戶:語法,選項和安全性最佳實踐May 13, 2025 am 12:12 AM

toaddauserinmysql,使用:createUser'username'@'host'Indessify'password'; there'showtodoitsecurely:1)choosethehostcarecarefullytocon trolaccess.2)setResourcelimitswithoptionslikemax_queries_per_hour.3)usestrong,iniquepasswords.4)Enforcessl/tlsconnectionswith

MySQL:如何避免字符串數據類型常見錯誤?MySQL:如何避免字符串數據類型常見錯誤?May 13, 2025 am 12:09 AM

toAvoidCommonMistakeswithStringDatatatPesInMysQl,CloseStringTypenuances,chosethirtightType,andManageEngencodingAndCollat​​ionsEttingSefectery.1)usecharforfixed lengengtrings,varchar forvariable-varchar forbariaible length,andtext/blobforlargerdataa.2 seterters seterters seterters

mySQL:字符串數據類型和枚舉?mySQL:字符串數據類型和枚舉?May 13, 2025 am 12:05 AM

mysqloffersechar,varchar,text,and denumforstringdata.usecharforfixed Lengttrings,varcharerforvariable長度,文本forlarger文本,andenumforenforcingDataAntegrityWithaEtofValues。

mysql blob:如何優化斑點請求mysql blob:如何優化斑點請求May 13, 2025 am 12:03 AM

優化MySQLBLOB請求可以通過以下策略:1.減少BLOB查詢頻率,使用獨立請求或延遲加載;2.選擇合適的BLOB類型(如TINYBLOB);3.將BLOB數據分離到單獨表中;4.在應用層壓縮BLOB數據;5.對BLOB元數據建立索引。這些方法結合實際應用中的監控、緩存和數據分片,可以有效提升性能。

將用戶添加到MySQL:完整的教程將用戶添加到MySQL:完整的教程May 12, 2025 am 12:14 AM

掌握添加MySQL用戶的方法對於數據庫管理員和開發者至關重要,因為它確保數據庫的安全性和訪問控制。 1)使用CREATEUSER命令創建新用戶,2)通過GRANT命令分配權限,3)使用FLUSHPRIVILEGES確保權限生效,4)定期審計和清理用戶賬戶以維護性能和安全。

掌握mySQL字符串數據類型:varchar vs.文本與char掌握mySQL字符串數據類型:varchar vs.文本與charMay 12, 2025 am 12:12 AM

chosecharforfixed-lengthdata,varcharforvariable-lengthdata,andtextforlargetextfield.1)chariseffity forconsistent-lengthdatalikecodes.2)varcharsuitsvariable-lengthdatalikenames,ballancingflexibilitibility andperformance.3)

MySQL:字符串數據類型和索引:最佳實踐MySQL:字符串數據類型和索引:最佳實踐May 12, 2025 am 12:11 AM

在MySQL中處理字符串數據類型和索引的最佳實踐包括:1)選擇合適的字符串類型,如CHAR用於固定長度,VARCHAR用於可變長度,TEXT用於大文本;2)謹慎索引,避免過度索引,針對常用查詢創建索引;3)使用前綴索引和全文索引優化長字符串搜索;4)定期監控和優化索引,保持索引小巧高效。通過這些方法,可以在讀取和寫入性能之間取得平衡,提升數據庫效率。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

MantisBT

MantisBT

Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

EditPlus 中文破解版

EditPlus 中文破解版

體積小,語法高亮,不支援程式碼提示功能

VSCode Windows 64位元 下載

VSCode Windows 64位元 下載

微軟推出的免費、功能強大的一款IDE編輯器

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強大的PHP整合開發環境

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )專業的PHP整合開發工具