如何設計百萬級以上規模專案的搜尋功能

2021-09-13 01:10:06 字數 1174 閱讀 9868

專案名:***平台

專案規模:100萬資料量

資料特徵:每條資訊有標題、作者、發布時間、唯一的識別碼、正文

其中標題識別碼是英文與數字的組合,正文假設500漢字。

一般專案,這裡特指資料量規模在1萬以下的規模,簡單的企業站、社群系統、部落格系統,資料量不大,搜尋功能直接用like查詢就能滿足使用需求,一般配置的伺服器2核4g就能發揮很好的效能了。

但是專案規模達到百萬級以上時,就不能用簡單的like查詢就行搜尋了。like查詢需要對資料表進行遍歷,需要把錶的內容載入至記憶體,這裡簡單計算下記憶體開銷:

100萬條資料,每條資訊500字正文

每個漢字是2個位元組,1024位元組=1kb,1024kb=1mb,1024mb=1g

100萬條資料全匹配產生的資料量大小是:1000000*500*2/1024/1024/1024≈1g,這裡不考慮分頁,1g資料的傳輸就會消消耗大量的頻寬資源,更不好說cpu和記憶體消耗了

因此,百萬級以上規模的搜尋功能,必須要使用sphinx這類專門的全文索引工具

like查詢沒有用到索引,需要對全表進行掃瞄,將所查到的每一行符合條件的資料放到結果集裡面,然後返給客戶端。

服務端並不需要儲存乙個完整的結果集,取資料和發資料流程如下:

獲取一行,寫到net_buffer中,它的記憶體的大小由引數net_buffer_length確定,預設16k;

重複獲取行,直到net_buffer寫滿,呼叫網路介面發出去;

如果傳送成功,清空net_buffer,然後繼續取下一行,重複1、2過程;

如果傳送函式返回eagain 或者 wsaewouldblock,此時表示「本地網路棧」(socket send buffer)寫滿了,進入等待(為什麼會寫滿,因為沒發出去)。直到網路棧重新可寫,再繼續傳送。

由取、發資料流程可知:

乙個查詢在傳送過程中,占用mysql的內部記憶體最大就是net_buffer_length,它是有上限控制的,並不會肆意占用記憶體;

socket send buffer (預設定義/proc/sys/net/core/wmem_default)也是有上限控制的,如果它被寫滿,就會暫停讀資料的流程。

like查詢有這以上2個瓶頸限制,導致查詢速度緩慢,全表掃瞄會占用大量的cpu效能,匹配到的結果傳送的過程中,又受到net_buffer和send_buffer的雙重限制,這決定了like查詢不適合處理10萬以上資料量的表

MySQL 百萬級以上分頁優化

正常我們碼農資料庫的時候一般都是以下這種查詢方式 select from table order by id limit 100000,10 但是以上這種查詢會導致我們資料慢死,一般我們採用以下方式 select from table order by id limit 1000000,10 以上這...

如何在生產環境刪除百萬級以上的資料

公司的使用者被人惡意註冊了,user id是連續著的,這些使用者現在要清理掉,但是資料量太大,如何快速生成200w的delete語句呢?ps 生產環境不建議delete from user where user id and user id sqlyog環境下快速生成語句 在伺服器上 select ...

如何在生產環境刪除百萬級以上的資料

原文 公司的使用者被人惡意註冊了,user id是連續著的,這些使用者現在要清理掉,但是資料量太大,如何快速生成200w的delete語句呢?ps 生產環境不建議delete from user where user id and user id sqlyog環境下快速生成語句 select con...