首先 來建立一張帶有FULLTEXT索引測試表 建表語句: html
FULLTEXT索引加在了vivo_tags字段上,關於FULLTEXT索引的介紹能夠參考《MySQL技術內幕——InnoDB存儲引擎》的P229~P248,也能夠參考https://www.cnblogs.com/tommy-huang/p/4483684.html在插入數據以前,咱們首先看一下當前數據庫所在的環境:數據庫
show global variables like 'innodb_buffer_pool_size'; #緩衝池總大小安全
show global variables like 'innodb_buffer_pool_instances'; #緩衝池的數量架構
可見測試環境music庫緩衝池128M,緩衝池有8個。併發
緩衝池用來彌補CPU和磁盤IO之間的鴻溝,在寫入數據的時候,首先修改緩衝池中的頁(頁是InnoDB存儲引擎最小的管理單位),再以必定的頻率刷新到磁盤上,而多個緩衝池能夠減小數據庫內部的資源競爭,增長數據庫的併發處理能力,所以緩衝池總大小和緩衝池數量都是決定數據庫處理性能的重要指標。這裏能夠擴大緩衝池size來提高插入速度,因爲是公共的測試環境,因此這裏不作修改。elasticsearch
innodb_flush_log_at_trx_commit :redo日誌刷新到磁盤的策略,默認爲1,即每次事務提交,都刷入到磁盤中。這是安全係數最高的同步策略,可是在大量數據插入時,會由於頻繁的磁盤IO操做,大大影響插入速度。性能
sync_binlog:二進制日誌刷到磁盤的策略,默認是0,也就是不開啓二進制日誌,但在不少主從數據庫架構中,這個參數都是大於0的。打開這個參數,也會大大影響插入速度。測試
寫一個批量插入的存儲過程:優化
這裏手動開啓了一個事務,手動控制每一萬條插入數據提交一次。這是由於,在默認條件下,插入操做每進行一次,就自動提交一次,若是插入1000萬條,就提交了1000萬次,這無疑是很崩潰的。可是這個10000次插入操做提交一次,也沒有通過嚴格驗證,是否就是最好的選擇,由於這和緩衝池大小有關係,若是插入10000條時,緩衝池已經滿了,也會強制刷入磁盤中,而若是緩衝池太大,10000次又顯得太少了。實際這邊能夠加一個記錄表,記錄每一次提交的成功與否狀況,能夠幫助咱們實時監控插入操做進行到哪裏進行得怎樣了,畢竟1000萬條的插入仍是至關漫長的。而後調用存儲過程:3d
實測用了大概28分鐘。當查詢含有100008這個字段的信息時,用like查詢:
用全文檢索查詢: 奇怪,怎麼全文檢索反而慢呢?緣由是,like查詢前10條的時候,是採用全表掃描的方式,一直查找滿10條的時候,就會返回數據。而回顧一下1.3中的存儲過程,能夠看到100008這個字段的命中率大約是33%,至關於,全表掃描到30條的時候,就已經拿到足夠的數據返回了。
可是當查詢第1000000到1000010條時,因爲要掃描大約3百萬條數據才能得到結果集,所以速度就很是慢了:
而反觀全文檢索的查詢方式,因爲採用的是倒排索引的實現方式,先是把全部100008的全部倒排索引列出來,而後在這個集合裏面取前10個,這裏100008的文檔數超過300萬,所以速度就比較慢了。爲了驗證這個觀點,我往t_song_info_test_test表中插入兩條數據
此時,200008在1千萬+2條數據中總共只出現了兩次。此時,執行查詢語句:
只花了0.047秒。長度小於4的字段,不會被記錄到全文檢索中,也就查不到結果
修改ft_min_word_len的值便可。全文檢索是根據空格符或者「,」這類的明顯的分隔符字段來分詞的。並不想elasticsearch那樣支持中文分詞,可是從MySQL 5.7.6開始,內置的InnoDB支持自定義分詞長度對中文進行分詞,能夠參考[www.jianshu.com/p/c48106149…](MySQL 5.7 中文全文檢索使用教程)。