專案名:***平台
專案規模: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...