久久精品五月,日韩不卡视频在线观看,国产精品videossex久久发布 ,久久av综合

站長資訊網(wǎng)
最全最豐富的資訊網(wǎng)站

聊聊MySQL全文索引怎么解決like模糊匹配查詢慢

聊聊MySQL全文索引怎么解決like模糊匹配查詢慢

程序員必備接口測試調(diào)試工具:立即使用
Apipost = Postman + Swagger + Mock + Jmeter
Api設(shè)計、調(diào)試、文檔、自動化測試工具
后端、前端、測試,同時在線協(xié)作,內(nèi)容實時同步

模糊查詢,如查詢姓名包含”曉“的用戶,常見的寫法為 like "%曉%",MySQL里面他會全表掃描,數(shù)據(jù)量少還好,全表掃描也很快,隨著數(shù)據(jù)增加會變慢,上ES又很重。本篇文章就來給大家介紹like模糊匹配查詢慢解決之道——MySQL全文索引。

需求

需要模糊匹配查詢一個單詞

select * from t_phrase where LOCATE('昌',phrase) = 0;

select * from t_chinese_phrase where instr(phrase,'昌') > 0;

select * from t_chinese_phrase where phrase like '%昌%'

explain一下看看執(zhí)行計劃

聊聊MySQL全文索引怎么解決like模糊匹配查詢慢

由explain的結(jié)果可知,雖然我們給phrase建了索引,但是查詢的時候,索引是失效的。

原因: mysql的索引是B+樹結(jié)構(gòu),InnoDB在模糊查詢數(shù)據(jù)時使用 "%xx" 會導(dǎo)致索引失效(此處就不展開講了)

從查詢時長上來看,花費時間:90ms

目前數(shù)據(jù)量:93230(9.3W)已經(jīng)需要90ms,這個時間不太能接受,假如數(shù)據(jù)量增加,這個時間會不斷增長。

解決方案:

數(shù)據(jù)量不大的情況下,使用mysql的全文索引;
數(shù)據(jù)量比較大或者mysql的全文索引不達(dá)預(yù)期的情況下,可以考慮使用ES

下面主要是MySQL的全文索引相關(guān).

全文索引介紹

1、發(fā)展歷史

  • 舊版的MySQL的全文索引只能用在MyISAM存儲引擎的char、varchar和text的字段上。

  • MySQL5.6.24上InnoDB引擎也加入了全文索引。

2、全文索引

  • 全文檢索(Full-Text Search) 是將存儲于數(shù)據(jù)庫中的整本書或整篇文章中的任意內(nèi)容信息查找出來的技術(shù)。它可以根據(jù)需要獲得全文中有關(guān)章、節(jié)、段、詞等信息,也可以進(jìn)行各種統(tǒng)計和分析

3、創(chuàng)建全文索引

若需對大量數(shù)據(jù)設(shè)置全文索引,建議先添加數(shù)據(jù)再創(chuàng)建索引。

1、創(chuàng)建表時創(chuàng)建全文索引

create table 表名( 字段名1, 字段名2, 字段名3, 字段名4, FULLTEXT full_index_name (字段名) )ENGINE=InnoDB;
登錄后復(fù)制

2、為已有表添加全文索引

create fulltext index 索引名稱 on 表名(字段名);

eg:

create table t_word (     id        int unsigned auto_increment comment '自增id' primary key,     uid       char(32)     not null comment '32位唯一id',     word      varchar(256) null comment '英文單詞',     translate varchar(256) null );  create fulltext index full_idx_translate     on t_word (translate);  create fulltext index full_idx_word     on t_word (word);  INSERT INTO t_word (id, uid, word, translate) VALUES (1, '9d592499c65648b0a9519206688ef3f9', 'lion', '獅子'); INSERT INTO t_word (id, uid, word, translate) VALUES (2, 'ce26ac4239514bc6af481bcb1d9b67df', 'panda', '熊貓'); INSERT INTO t_word (id, uid, word, translate) VALUES (3, 'a7d6042853c44904b68275daafb44702', 'tiger', '老虎'); INSERT INTO t_word (id, uid, word, translate) VALUES (4, 'f13bd0a8ecea44fc9ade1625eeb4cc3c', 'goat', '山羊'); INSERT INTO t_word (id, uid, word, translate) VALUES (5, '27d5cbfc93a046388d712085e567474f', 'sheep', '綿羊'); INSERT INTO t_word (id, uid, word, translate) VALUES (6, 'ed35df138cf348aa937781be8ee21cbf', 'lamb', '羊羔'); INSERT INTO t_word (id, uid, word, translate) VALUES (7, 'fba5861d9527440990276e999f47ef8f', 'buffalo', '水牛'); INSERT INTO t_word (id, uid, word, translate) VALUES (8, '3a72e76f210841b1939fff0d3d721375', 'bull', '公牛'); INSERT INTO t_word (id, uid, word, translate) VALUES (9, '272e0b28ea7a48248a86f17533bf9943', 'cow', '母牛'); INSERT INTO t_word (id, uid, word, translate) VALUES (10, '47127adface54e418e4c1b9980af6d16', 'calf', '小牛'); INSERT INTO t_word (id, uid, word, translate) VALUES (11, '10592499c65648b0a9519206688ef3f9', 'little lion', '小獅子'); INSERT INTO t_word (id, uid, word, translate) VALUES (12, '1bf095110b634a01bee5b31c5ee7ee0c', 'little cow', '母牛'); INSERT INTO t_word (id, uid, word, translate) VALUES (13, '4813e588cde54c30bd65bfdbb243ad1f', 'little calf', '小小牛'); INSERT INTO t_word (id, uid, word, translate) VALUES (14, '5e377e281ad344048b6938a638b78ccb', 'little bull', '小公牛'); INSERT INTO t_word (id, uid, word, translate) VALUES (15, '2855ad0da2964c7682c178eb8271f13d', 'little buffalo', '小水牛'); INSERT INTO t_word (id, uid, word, translate) VALUES (16, '72f24c9a77644d57a36f3bdf2b8116b0', 'little lamb', '小羊羔'); INSERT INTO t_word (id, uid, word, translate) VALUES (17, '2d592499c65648b0a9519206688ef3f9', 'I''m a big lion', '我是一只大獅子');
登錄后復(fù)制

3、刪除全文索引

alter table 表名 drop index 索引名;

4、全文索引使用

語法

MATCH(col1,col2,...) AGAINST(expr[search_modifier]) search_modifier: {     IN NATURAL LANGUAGE MODE     | IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION     | IN BOOLEAN MODE     | WITH QUERY EXPANSION }
登錄后復(fù)制

4.1 IN NATURAL LANGUAGE MODE

自然語言模式是MySQL 默認(rèn) 的全文檢索模式。自然語言模式不能使用操作符,不能指定關(guān)鍵詞必須出現(xiàn)或者必須不能出現(xiàn)等復(fù)雜查詢。

// 默認(rèn)是使用 in natural language mode select * from t_word where match(word) against ('lion'); // 或者 顯示寫 select * from t_word where match(word) against ('lion' in natural language mode);
登錄后復(fù)制

登錄后復(fù)制

結(jié)果如下:

聊聊MySQL全文索引怎么解決like模糊匹配查詢慢

4.2 IN BOOLEAN MODE

BOOLEAN模式可以使用操作符,可以支持指定關(guān)鍵詞必須出現(xiàn)或者必須不能出現(xiàn)或者關(guān)鍵詞的權(quán)重高還是低等復(fù)雜查詢。推薦使用boolean模式

操作者 描述
為空 默認(rèn),包含該詞
+ 包括,這個詞必須存在。
排除,詞不得出現(xiàn)。
>(大于號) 包括,并提高排名值,查詢的結(jié)果會靠前
< 包括,并降低排名值,查詢的結(jié)果會靠后
() 將單詞分組為子表達(dá)式(允許將它們作為一組包括在內(nèi),排除在外,排名等等)。
? 否定單詞的排名值。
* 通配符在這個詞的結(jié)尾。
“” 定義短語(與單個單詞列表相對,整個短語匹配以包含或排除)。

示例:

// 默認(rèn)是使用 in natural language mode select * from t_word where match(word) against ('lion'); // 或者 顯示寫 select * from t_word where match(word) against ('lion' in natural language mode);
登錄后復(fù)制

登錄后復(fù)制

聊聊MySQL全文索引怎么解決like模糊匹配查詢慢

// 排除包含lion記錄、查詢出包含cow或者little的記錄,提升包含calf單詞的排名,降低包含cow記錄的排名,查詢出以go開頭的記錄 select * from t_word where match(word) against ('-lion cow little >calf <cow  go*' in boolean mode) ;
登錄后復(fù)制

聊聊MySQL全文索引怎么解決like模糊匹配查詢慢

好像問題都解決了, 但是問題才剛開始


回到最開始的需求,我想模糊搜索

select * from t_word where  match(word) against('lio' in boolean mode);
登錄后復(fù)制

預(yù)期值:把包含lion的都查詢出來 實際結(jié)果:啥都沒有。

聊聊MySQL全文索引怎么解決like模糊匹配查詢慢

全匹配查詢的時候能查詢出來

select * from t_word where  match(translate) against('小水牛' in boolean mode);
登錄后復(fù)制

聊聊MySQL全文索引怎么解決like模糊匹配查詢慢

只查詢部分查詢不出來。如:下面只查詢 "小水" 或者"水牛" 都沒有數(shù)據(jù)

select * from t_word where  match(translate) against('小水' in boolean mode);
登錄后復(fù)制

聊聊MySQL全文索引怎么解決like模糊匹配查詢慢

奇怪了,這咋沒出來呢?

全文索引默認(rèn)是只按照空格進(jìn)行分詞的,所以當(dāng)我完整的單個單詞去查詢的時候是能查出來的。但是使用部分單詞去查詢或者使用部分中文去查詢時,是查詢不出來數(shù)據(jù)的,像中文需要使用中文分詞器進(jìn)行分詞。

中文分詞與全文索引

InnoDB默認(rèn)的全文索引parser非常合適于Latin,因為Latin是通過空格來分詞的。但對于像中文,日文和韓文來說,沒有這樣的分隔符。一個詞可以由多個字來組成,所以我們需要用不同的方式來處理。在MySQL 5.7.6中我們能使用一個新的全文索引插件來處理它們:N-gram parser。

什么是N-gram?

在全文索引中,n-gram就是一段文字里面連續(xù)的n個字的序列。例如,用n-gram來對“齒輪傳動”來進(jìn)行分詞,得到的結(jié)果如下:

N=1 : '齒', '輪', '傳', '動'; N=2 : '齒輪', '輪傳', '傳動'; N=3 : '齒輪傳', '輪傳動'; N=4 : '齒輪傳動';
登錄后復(fù)制

這個上面這個N是怎么去配置的?

查一下目前的值

show variables like '%token%';
登錄后復(fù)制

聊聊MySQL全文索引怎么解決like模糊匹配查詢慢

參數(shù)解析:

innodb_ft_min_token_size
默認(rèn)3,表示最小3個字符作為一個關(guān)鍵詞,增大該值可減少全文索引的大小
innodb_ft_max_token_size
默認(rèn)84,表示最大84個字符作為一個關(guān)鍵詞,限制該值可減少全文索引的大小
ngram_token_size
默認(rèn)2,表示2個字符作為內(nèi)置分詞解析器的一個關(guān)鍵詞,合法取值范圍是1-10,如對“abcd”建立全文索引,關(guān)鍵詞為’ab’,‘bc’,‘cd’ 當(dāng)使用ngram分詞解析器時,innodb_ft_min_token_size和innodb_ft_max_token_size 無效

修改方式

方式1: 在my.cnf中修改/添加參數(shù)

[mysqld]ngram_token_size = 1
登錄后復(fù)制

方式2: 修改啟動參數(shù)

mysqld --ngram_token_size=1復(fù)制代碼
登錄后復(fù)制

參數(shù)均不可動態(tài)修改,修改后需重啟MySQL服務(wù),并重新建立全文索引

實際使用

初始化測試數(shù)據(jù)

這里只提供部分測試數(shù)據(jù),我下面sql使用全量數(shù)據(jù),數(shù)據(jù)對不上

create table t_chinese_phrase (     id     int unsigned auto_increment comment 'id'         primary key,     phrase varchar(32) not null comment '詞組' )     collate = utf8mb4_general_ci;  INSERT INTO t_chinese_phrase (id, phrase) VALUES (278911, '阿昌族'); INSERT INTO t_chinese_phrase (id, phrase) VALUES (279253, '八一南昌起義'); INSERT INTO t_chinese_phrase (id, phrase) VALUES (282316, '昌明'); INSERT INTO t_chinese_phrase (id, phrase) VALUES (282317, '昌盛'); INSERT INTO t_chinese_phrase (id, phrase) VALUES (282318, '昌言'); INSERT INTO t_chinese_phrase (id, phrase) VALUES (286534, '東昌紙'); INSERT INTO t_chinese_phrase (id, phrase) VALUES (291525, '海昌藍(lán)'); INSERT INTO test.t_chinese_phrase (id, phrase) VALUES (346682, '繁榮昌盛'); INSERT INTO test.t_chinese_phrase (id, phrase) VALUES (282317, '昌盛'); INSERT INTO test.t_chinese_phrase (id, phrase) VALUES (287738, '繁盛'); INSERT INTO test.t_chinese_phrase (id, phrase) VALUES (287736, '繁榮');
登錄后復(fù)制

添加索引

mysql 全文索引使用倒排索引為 full inverted index
結(jié)構(gòu):{單詞,(單詞所在文檔的ID,單詞在具體文件中的位置)}

添加索引:

alter  table t_chinese_phrase add fulltext ful_phrase (phrase) with parser ngram;
登錄后復(fù)制

建完索引,我們可以通過查詢INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE和INFORMATION_SCHEMA.INNODB_FT_TABLE_TABLE來查詢哪些詞在全文索引里面。這是一個非常有用的調(diào)試工具。如果我們發(fā)現(xiàn)一個包含某個詞的文檔,沒有如我們所期望的那樣出現(xiàn)在查詢結(jié)果中,那么這個詞可能是因為某些原因不在全文索引里面。比如,它含有stopword,或者它的大小小于ngram_token_size等等。這個時候我們就可以通過查詢這兩個表來確認(rèn)。下面是一個簡單的例子:

# test: 庫名  t_chinese_phrase: 表名字 SET GLOBAL innodb_ft_aux_table="test/t_chinese_phrase"; # 查詢分詞情況 SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE; # 查詢分詞情況 select * from information_schema.innodb_ft_index_table;
登錄后復(fù)制

查詢結(jié)果如下:

聊聊MySQL全文索引怎么解決like模糊匹配查詢慢

因為我們上面設(shè)置了分詞數(shù)是1,所以,可以看到都是按照一個詞進(jìn)行分詞的。

字段解析:
FIRST_DOC_ID :word第一次出現(xiàn)的文檔ID
LAST_DOC_ID : word最后一次出現(xiàn)的文檔ID
DOC_COUNT :含有word的文檔個數(shù)
DOC_ID :當(dāng)前文檔ID
POSITION : word 當(dāng)在前文檔ID的位置

查詢

1、使用自然語言模式 NATURAL LANGUAGE MODE 查詢

在自然語言模式(NATURAL LANGUAGE MODE)下,文本的查詢被轉(zhuǎn)換為n-gram分詞查詢的并集。

例如,當(dāng)ngram_token_size = 1 時,(‘繁榮昌盛’)轉(zhuǎn)換為(‘繁 榮 昌 盛’)。下面一個例子:

SELECT * FROM t_chinese_phrase WHERE MATCH (phrase) AGAINST ('繁榮昌盛' in natural language mode) ;
登錄后復(fù)制

聊聊MySQL全文索引怎么解決like模糊匹配查詢慢

2、使用布爾模式(BOOLEAN MODE)查詢

布爾模式(BOOLEAN MODE)文本查詢被轉(zhuǎn)化為n-gram分詞的短語查詢

例如,當(dāng)ngram_token_size = 1 時,(‘繁榮昌盛’)轉(zhuǎn)換為(‘”繁榮昌盛“’)。下面一個例子:

SELECT * FROM t_chinese_phrase WHERE MATCH (phrase) AGAINST ('繁榮昌盛' in boolean  mode) ;
登錄后復(fù)制

聊聊MySQL全文索引怎么解決like模糊匹配查詢慢

實際使用

回到我們最開始的查詢需求,看看實際的效果

查詢包含了“昌”的數(shù)據(jù)

SELECT * FROM t_chinese_phrase WHERE MATCH (phrase) AGAINST ('昌' IN boolean  MODE) ; SELECT * FROM t_chinese_phrase WHERE MATCH (phrase) AGAINST ('昌' ) order by id asc;
登錄后復(fù)制

聊聊MySQL全文索引怎么解決like模糊匹配查詢慢

可以看到結(jié)果:目前“昌”在任意位置都能被查詢到。

查詢執(zhí)行計劃如下:

聊聊MySQL全文索引怎么解決like模糊匹配查詢慢

耗時31ms(不走索引是90ms),耗時差不多是之前的1/3。

注意點

1、自然語言全文索引創(chuàng)建索引時的字段需與查詢的字段保持一致,即MATCH里的字段必須和FULLTEXT里的一模一樣;

2、自然語言檢索時,檢索的關(guān)鍵字在所有數(shù)據(jù)中不能超過50%(即常見詞),則不會檢索出結(jié)果??梢酝ㄟ^布爾檢索查詢;

3、在mysql的stopword中的單詞檢索不出結(jié)果??赏ㄟ^

SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_DEFAULT_STOPWORD
登錄后復(fù)制

查詢所有的stopword。遇到這種情況,有兩種解決辦法:

(1)stopword一般是mysql自建的,但可以通過設(shè)置ft_stopword_file變量為自定義文件,從而自己設(shè)置stopword,設(shè)置完成后需要重新創(chuàng)建索引。但不建議使用這種方法;

(2)使用布爾索引查詢。

4、小于最短長度和大于最長長度的關(guān)鍵詞無法查出結(jié)果。可以通過設(shè)置對應(yīng)的變量來改變長度限制,修改后需要重新創(chuàng)建索引。

myisam引擎下對應(yīng)的變量名為ft_min_word_len和ft_max_word_len

innodb引擎下對應(yīng)的變量名為innodb_ft_min_token_size和innodb_ft_max_token_size

5、MySQL5.7.6之前的版本不支持中文,需使用第三方插件

6、全文索引只能在 InnoDB(MySQL 5.6以后) 或 MyISAM 的表上使用,并且只能用于創(chuàng)建 char,varchar,text 類型的列。

贊(0)
分享到: 更多 (0)
?
網(wǎng)站地圖   滬ICP備18035694號-2    滬公網(wǎng)安備31011702889846號
久久精品五月,日韩不卡视频在线观看,国产精品videossex久久发布 ,久久av综合
美日韩精品视频| 久久精品国产亚洲夜色av网站| 一区免费视频| 欧美aa国产视频| 极品裸体白嫩激情啪啪国产精品| 久久久久国产精品一区三寸| 香蕉视频亚洲一级| 99国产精品免费视频观看| 在线看片福利| 99成人在线视频| 中国女人久久久| 亚洲精品日韩久久| 欧美久久一区二区三区| 国产精品久久久久久久久久白浆 | 亚洲一级少妇| 999精品在线| av亚洲免费| 老司机精品久久| 日韩动漫一区| 精品伊人久久| 蜜桃av在线播放| 免费污视频在线一区| 蜜臀久久99精品久久一区二区| 伊人久久婷婷| 日韩欧美另类中文字幕| 国产美女视频一区二区| 久久午夜影院| 久久久影院免费| 蜜桃视频在线观看一区| 日韩1区2区3区| 成人国产精品久久| 亚洲激情av| 日本免费在线视频不卡一不卡二| 麻豆一区二区99久久久久| av中文字幕在线观看第一页| 99成人在线视频| 中文视频一区| 国产精品一区二区三区美女| 伊人网在线播放| 丝袜美腿成人在线| 国产精品自在| 99视频精品全部免费在线视频| 三级欧美韩日大片在线看| 国产欧美一区二区三区国产幕精品| 福利一区视频| 噜噜噜久久亚洲精品国产品小说| 欧美日韩一视频区二区| 亚洲国产欧美日本视频| 亚洲天堂av资源在线观看| 精品久久不卡| 午夜亚洲一区| 国产精品免费99久久久| 999久久久亚洲| 欧美一级二区| 99精品电影| 国产午夜精品一区在线观看| 久久久久久久久丰满| 日韩毛片一区| 久久亚洲国产| 国产日韩欧美一区二区三区| 亚洲无线一线二线三线区别av| 欧美片网站免费| 偷拍欧美精品| 久久精品理论片| 六月婷婷一区| 日本不卡免费高清视频在线| 中文无码日韩欧| www.九色在线| 日本不卡高清| 亚洲第一区色| 久久久91麻豆精品国产一区| 中国女人久久久| а√在线中文在线新版| 亚洲一区二区免费在线观看| 日本美女一区| 国产激情久久| 亚洲一区二区三区四区电影 | 国产剧情在线观看一区| 黄页网站一区| 都市激情国产精品| 五月激激激综合网色播| 日韩精品影视| 久久精品一本| 欧美精品三级在线| 丝袜美腿成人在线| 欧美亚洲在线日韩| 免费在线欧美黄色| 日本不卡中文字幕| 最新亚洲激情| 日韩精品午夜| 91亚洲国产高清| 国产精品对白| 日本午夜免费一区二区| 亚洲一区欧美激情| 久久亚洲国产| 国产一区二区色噜噜| 欧美日韩精品一区二区三区视频 | 日韩国产91| 久久av在线| 激情综合网址| 日韩视频网站在线观看| 麻豆中文一区二区| 91麻豆精品激情在线观看最新 | 91九色精品国产一区二区| 美女尤物国产一区| 国产日韩亚洲| 日韩精品一级| 中文字幕一区二区三区在线视频| 亚洲高清激情| 国产在线|日韩| 国产suv精品一区二区四区视频| 久久av免费| 国产欧美日韩一级| 欧美亚洲一区二区三区| 日韩精品91亚洲二区在线观看| 日韩中文字幕麻豆| 视频一区二区三区在线| 久色成人在线| 蜜臀国产一区二区三区在线播放| 国产一在线精品一区在线观看| 日韩欧美一区二区三区在线观看 | 国产在线一区不卡| 高清一区二区| 精品72久久久久中文字幕| 国产精品乱战久久久| 国产精品入口久久| 国产欧美日韩在线观看视频| 国产精品一卡| 欧美国产先锋| 精品91福利视频| 精品久久福利| 亚洲深夜视频| 999久久久免费精品国产| 久久久久久久久99精品大| 欧美成人亚洲| 美女国产一区| 日本va欧美va瓶| 国产欧美高清视频在线| 久久av影院| 国产日韩电影| 999国产精品视频| 亚洲综合三区| 日韩欧美激情电影| 欧美激情aⅴ一区二区三区 | 日韩**一区毛片| 国产午夜一区| 国产一区福利| 欧美日中文字幕| 午夜一区在线| 欧美天堂在线| 精品国产午夜肉伦伦影院| 日韩理论片av| 玖玖精品视频| 国产精品密蕾丝视频下载| 国产一区二区三区视频在线| 天堂日韩电影| 午夜在线播放视频欧美| 亚洲区第一页| 国产精品99久久久久久董美香| 国产精品毛片久久| 女人天堂亚洲aⅴ在线观看| 一区二区国产在线观看| 国产麻豆精品| 久久国产毛片| 中文字幕日本一区二区| 国产精品天堂蜜av在线播放| 91亚洲自偷观看高清| 欧美美女一区| 欧美日一区二区在线观看| 97精品国产| 国产色综合网| 国产精品网址| 欧美freesex黑人又粗又大| 视频在线观看一区| 精品免费av一区二区三区| 欧美福利在线| 国产精区一区二区| 久久精品国产亚洲夜色av网站| 四虎成人精品一区二区免费网站| 久久这里只有精品一区二区| 免费不卡中文字幕在线| 久久国产麻豆精品| 久久精品亚洲人成影院| 日韩在线成人| 日韩精品永久网址| 五月激激激综合网色播| 日韩欧美精品| 亚洲精品黄色| 久久精品中文| 国产精品主播在线观看| 91高清一区| 久久不见久久见国语| aa亚洲婷婷| 国产成人精品一区二区免费看京| 伊人久久大香伊蕉在人线观看热v| 精品亚洲成人| 男人的天堂久久精品| 国产精品成人a在线观看| 久久国产精品亚洲77777| yellow在线观看网址|