问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

最新版本的mysql的innodb类型,支持全文索引吗?

发布网友 发布时间:2022-04-30 20:32

我来回答

3个回答

懂视网 时间:2022-05-01 00:53

GLOBAL innodb_ft_aux_table=‘test/fts_a‘;

可以在information_schema架构下的表INNODB_FT_INDEX_TABLE得到表fts_a中的分词信息。

对于InnoDB存储引擎而言,其总是在事务提交时将分词写入到FTS Index Cache,然后通过批量写入到磁盘。虽然InnoDB存储引擎通过一种延时的、批量的写入方式来提高数据库的性能,但是上述操作仅在事务提交时发生。

当数据库关闭时,在FTS Index Cache中的数据库会同步到磁盘上的Auxiliary Table中。如果当数据库发生宕机时,一些FTS Index Cache中的数据可能未同步到磁盘上,那么下次重启数据库时,当用户对表进行全文检索(查询、插入)时,InnoDB存储引擎会自动读取未完成的文档,然后进行分词操作,再将分词结果放到FTS Index Cache

为了支持全文检索,必须有一个列与word进行映射。在InnoDB中这个列被命名成FTS_DOC_ID,其类型为BIGINT UNSIGNED NOT NULL,并且InnoDB存储引擎自动会在该列加上一个名为FTS_DOC_ID_INDEX的Unique Index.这些操作由存储引擎自己完成,用户也可以在建表时自动添加FTS_DOC_ID,以及对应的Unique Index。由于列名FTS_DOC_ID聚友特殊意义,因此在创建时必须注意相应的类型,否则会报错

技术分享

可以看到,由于用户手动定义FTS_DOC_ID为INT,而非BIGINT因此在创建时候会抛出异常,应该将此处修改成对应的BIGINT即可

文档中的分词的插入操作是在事务提交时完成,但是对于删除操作,其在事务提交时,不删除磁盘Auxiliary Table的记录,而只是删除FTS Cache Index记录,对于Auxiliary Table中被删除的记录,存储引擎会记录其FTS DOCUMENT ID ,并将其保存在DELETE auxiliary table中,在设置参数innodb_ft_aux_table后,用户可以访问information_schema架构下的表INNODB_FT_DELETED来观察删除的FTS Document ID

由于文档的DML操作实际并不删除索引中的数据,相反还会在对应的DELETED表中插入记录,因此随着应用程序的允许,索引会变得越来越大,即使索引中的有些数据已经被删除,查询也不会选择这类记录,为此,InnoDB提供了一种方式,允许用户手工将已删除的记录从索引中彻底删除,这就是OPTIMIZE TABLE。因为OPTIMIZE TABLE还会进行一些其他的操作。如Cardinality重新统计,若用户希望对倒排索引进行操作,可以通过innodb_optimize_fulltext_only设置

SET GLOBAL innodb_optimize_fulltext_only=1;

OPTIMIZE TABLE fts_a;

若被删除的文档很多,那么OPTIMIZE TABLE操作可能占用非常多的时间,会影响到程序并发性,并极大的降低用户的响应时间,用户可以通过参数innodb_ft_num_word_optimize来限制每次实际删除的分词数量,默认为2000

CREATE TABLE fts_a(
FTS_DOC_ID BIGINT UNSIGNED AUTO_INCREMENT NOT NULL,
body TEXT,
PRIMARY KEY(FTS_DOC_ID)
);


INSERT INTO fts_a SELECT NULL,‘pease porridge in the post‘;
INSERT INTO fts_a SELECT NULL,‘pease porridge hot,pease porridge cold‘;
INSERT INTO fts_a SELECT NULL,‘Nine days old‘;
INSERT INTO fts_a SELECT NULL,‘Some like it hot,some like it cold‘;
INSERT INTO fts_a SELECT NULL,‘Some like it the pot‘;
INSERT INTO fts_a SELECT NULL,‘Nine days old‘;
INSERT INTO fts_a SELECT NULL,‘I like code days‘;

CREATE FULLTEXT INDEX idx_fts ON fts_a(body);

查看数据

mysql> select * from fts_a;
+------------+----------------------------------------+
| FTS_DOC_ID | body     |
+------------+----------------------------------------+
|  1 | pease porridge in the post  |
|  2 | pease porridge hot,pease porridge cold |
|  3 | Nine days old    |
|  4 | Some like it hot,some like it cold |
|  5 | Some like it the pot   |
|  6 | Nine days old    |
|  7 | I like code days   |
+------------+----------------------------------------+
7 rows in set (0.00 sec)
mysql> set global innodb_ft_aux_table=‘iot2/fts_a‘;
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT * FROM information_schema.`INNODB_FT_INDEX_TABLE`;
+----------+--------------+-------------+-----------+--------+----------+
| WORD | FIRST_DOC_ID | LAST_DOC_ID | DOC_COUNT | DOC_ID | POSITION |
+----------+--------------+-------------+-----------+--------+----------+
| code | 7 | 7 | 1 | 7 | 7 |
| cold | 2 | 4 | 2 | 2 | 34 |
| cold | 2 | 4 | 2 | 4 | 30 |
| days | 3 | 7 | 3 | 3 | 5 |
| days | 3 | 7 | 3 | 6 | 5 |
| days | 3 | 7 | 3 | 7 | 12 |
| hot | 2 | 4 | 2 | 2 | 15 |
| hot | 2 | 4 | 2 | 4 | 13 |
| like | 4 | 7 | 3 | 4 | 5 |
| like | 4 | 7 | 3 | 4 | 17 |
| like | 4 | 7 | 3 | 5 | 5 |
| like | 4 | 7 | 3 | 7 | 2 |
| nine | 3 | 6 | 2 | 3 | 0 |
| nine | 3 | 6 | 2 | 6 | 0 |
| old | 3 | 6 | 2 | 3 | 10 |
| old | 3 | 6 | 2 | 6 | 10 |
| pease | 1 | 2 | 2 | 1 | 0 |
| pease | 1 | 2 | 2 | 2 | 0 |
| pease | 1 | 2 | 2 | 2 | 19 |
| porridge | 1 | 2 | 2 | 1 | 6 |
| porridge | 1 | 2 | 2 | 2 | 6 |
| porridge | 1 | 2 | 2 | 2 | 19 |
| post | 1 | 1 | 1 | 1 | 22 |
| pot | 5 | 5 | 1 | 5 | 17 |
| some | 4 | 5 | 2 | 4 | 0 |
| some | 4 | 5 | 2 | 4 | 17 |
| some | 4 | 5 | 2 | 5 | 0 |
+----------+--------------+-------------+-----------+--------+----------+
27 rows in set (0.00 sec)

可以看到每个word对应一个DOC_ID和POSITION。此外,还记录了FIRST_DOC_ID、LAST_DOC_ID、DOC_COUNT分别代表该word第一次出现文档的ID,最后一次出现的文档ID,以及该word在多少个文档中存在。

若此时执行下面的SQL语句,会删除FTS_DOC_ID为7的文档

DELETE FROM fts_a WHERE FTS_DOC_ID=7;

InnoDB存储引擎并不会直接删除索引中对应的记录,而是将删除的文档ID插入到DELETED表

SELECT * FROM information_schema.`INNODB_FT_DELETED`;

技术分享

如果用户想要彻底删除倒排索引中该文档的分词信息,可以

mysql> SET GLOBAL innodb_optimize_fulltext_only=1;
Query OK, 0 rows affected (0.00 sec)

mysql> OPTIMIZE TABLE fts_a;
+------------+----------+----------+----------+
| Table | Op | Msg_type | Msg_text |
+------------+----------+----------+----------+
| iot2.fts_a | optimize | status | OK |
+------------+----------+----------+----------+
1 row in set (0.08 sec)

mysql> SELECT * FROM information_schema.`INNODB_FT_DELETED`;
+--------+
| DOC_ID |
+--------+
| 7 |
+--------+
1 row in set (0.00 sec)

mysql> SELECT * FROM information_schema.`INNODB_FT_BEING_DELETED`;
+--------+
| DOC_ID |
+--------+
| 7 |
+--------+
1 row in set (0.00 sec)

运行OPTIMIZE TABLE 可以将记录彻底删除,并且彻底删除的文档ID会记录到INNODB_FT_BEGIN_DELETED中。此外,由于7这个文档一倍删除,因此不允许在插入这个文档ID,否则会抛出异常

mysql> INSERT INTO fts_a SELECT 7,‘I like this days‘;
ERROR 182 (HY000): Invalid InnoDB FTS Doc ID

stopword列表(stopword list)是本节最后阐述的一个概念,其表示该列表中的word不需要对其进行索引分词操作。例如,对于the这个单词,由于其不具有具体的意义,因此将其视为stopword,InnoDB存储引擎有一张默认的stopword列表,在information_schema架构下,表名为INNODB_FT_DEFAULT_STOPWORD,默认为36个stopword可以通过参数innodb_ft_server_stopword_table来定义stopword列表,如

mysql> CREATE TABLE innodb_ft_bug (
 -> value VARCHAR(18) NOT NULL DEFAULT ‘‘
 -> ) ENGINE=INNODB DEFAULT CHARSET=utf8; #此处必须为utf8不然会碰到bug
Query OK, 0 rows affected (0.07 sec)

mysql> SET GLOBAL innodb_ft_server_stopword_table=‘iot2/innodb_ft_bug‘;
Query OK, 0 rows affected (0.00 sec)

遇到bug的情形

mysql> CREATE TABLE user_stopword(VALUE VARCHAR(30))ENGINE=INNODB;
Query OK, 0 rows affected (0.03 sec)
mysql> SET GLOBAL innodb_ft_server_stopword_table=‘iot2/user_stopword‘;
ERROR 1231 (42000): Variable ‘innodb_ft_server_stopword_table‘ can‘t be set to the value of ‘iot2/user_stopword‘

观察错误日志提示

InnoDB: invalid column name for stopword table iot2/user_stopword. Its first column must be named as ‘value‘.

 

 

 

使用全文检索还有以下限制

每张表只能有一个全文检索的索引

由多列组合而成的全文检索的索引必须使用相同的字符集与排序规则

不支持没有单词界定符delimiter的语言,如中文 日文汉语等

 

 

 

 

MySQL中InnoDB全文检索

标签:

热心网友 时间:2022-04-30 22:01

mysql 5.6新特性------innodb

-- Innodb 增强

-- 更好的性能,扩展

-- 多核CPU服务器上提高性能

-- 提高线程调度:如分拆kernel
mutex;flush操作从主线程分离;多个perge线程;大内存优化等

-- 在数据文件扩展期间减少竞争

-- 现在在非递归情况下死锁检测:死锁信息可以记录到 error 日志,方便分析

-- 改进LRU flushing

-- 增加最大redo log大小:2 TB

-- undo log到单独表空间

-- 快速校验

-- 更好的恢复

-- Dump和恢复 buffer pool

-- 更好的可用性:新的information_schema(metrics,system和buffer
pool信息)

-- 全文本搜索(full-text search)

-- 可变的page大小:4k,8k

-- 更大的前缀索引:*3072 bytes

--------明确指出,innodb支持全文索引追问性能和myisam比呢

追答mysql5.6我还没有做过测试,这个需要你去造点数据试试了

热心网友 时间:2022-04-30 23:19

mysql5.6是支持全文索引的,但是记住哦,全文索引并不支持中文的!如果是中英文混合或纯粹中文的信息,就不要用全文索引

注:mysql下面有支持中文全文索引的开源项目,不过不是mysql官方的东西;有兴趣,自己可以搜一下
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
轻度慢性萎缩性胃炎 活动期,伴轻度肠 化 胃角多发糜烂。医生说了我... 胃窦粘膜慢性轻度萎缩性炎伴轻度肠化胃窦粘膜慢性轻度萎缩性炎? 芬兰留学读研费用是多少 芬兰留学读研时间 去芬兰留学学费生活费一年要多少 芬兰留学读研费用是多少? 芬兰留学读研学费多少? 感冒好多天了,可不可以打蓝球或者其它运动出出汗啊? 感冒打喷嚏,鼻塞然后可以让自己多出出汗吗 宝宝感冒了能去游泳吗 红米k40被偷了,我用别的手机登入小米账号,如果他开了飞行模式我还可以定位到吗?如果那部手机被刷机_百度问一问 江波龙上市了吗? 小米或在印度与TikTok展开合作,这会给小米公司带来什么改变? 社交软件探探密码忘记了 注册的手机号码没用了 收不到验证码 这样找回密码? 探探用未注册的手机号登录会直接发送验证码吗 如图游标卡尺的读数为___cm 如图所示,游标卡尺的读数是___cm 手机忘记密码,iPhone 已停用,但我想将里面的相片导出来,不过锁机了? 游标卡尺读数:___cm螺旋测微器的读数:___mm 游标卡尺的读数为___cm. 螺旋测微器的读数为___mm 如图所示,游标卡尺读出的数值是___ cm 读出图中游标卡尺的读数.图1读数___mm; 图2读数___cm 苹果手机开不开机 有锁屏 想把照片倒出来 怎么办 写出游标卡尺的读数(1)读数是______ cm ... 在疯狂动物园里有哪十句话特别有意义? 手机号都有,但搜索不到抖音号,为什么?把我设置了还是设置了所有有人_百度问一问 疯狂动物园第6种动物是什么 疯狂动物园的8种牛 疯狂动物园最稀有的动物是什么? 疯狂动物园动物设施有什么作用 模拟火车12的介绍 模拟火车12和模拟火车2012有什么区别 模拟火车12怎么导入mod 笔记本 触摸板指示灯不会亮 有那些火车游戏 我的戴尔电脑触摸板上方的灯怎么开啊? 看我配置能玩模拟火车哪一款? 触摸板的灯不亮了?怎么按也不亮?不能锁定触摸板 模拟火车2006的游戏简介 求一款火车的电脑游戏 模拟火车分类 模拟火车 《铁路工厂》和《模拟火车》是同一个游戏么? 炫龙炎魔T1的触摸板是背光的吗?键盘灯亮了 但是触摸板不亮。 模拟火车2015值得入吗?还是说等新时代 superga鞋子属于什么档次的牌子? 《微软模拟火车》是怎么样的一款游戏呢? superga天猫上是正品吗? 黎民的同义词 我买一个移动硬盘里有模拟火车2020怎样打开?