如何在mysql中使用覆盖索引加速查询

哦,说一下我在MySQL中使用覆盖索引时遇到的一些陷阱。

当时公司有一个电子商务系统,用户数量较多,订单量巨大。
用户每天都在查看订单,老板很担心。
DBA老王思考优化。
他观察了很长时间,发现用户经常按user_id或status查看订单,有时会被要求按create_time排序。
最后,我选择了 user_id、status 和 amount 字段。
如您所知,这种需求是非常真实的。

老王建了复合索引 CREATE INDEX idx_user_status_time ONorders(user_id, status, create_time, amount);现在检查 SELECT user_id, status, amount FROMorders WHERE user_id=1 2 3 AND status=1 ORDER BY create_time DESC;在此查询计划中,Extra 字段显示“使用索引”。
想一想。
直接从索引检索数据,而不将其放回表中。
什么速度啊!它从固定状态快速进展到狗状态。

然而,这并非没有代价。
想一想,这个索引里面塞满了user_id、status、create_time、amount。
索引文件应该有多大?每次增加或修改订单时,不仅要修改数据行,还必须同时更新索引,影响写入性能。
我有一张有很多字段的表。
王先生很高兴在索引中添加了这么多列。
结果,服务器的内存突然被占满,写入延迟变得难以承受。
这太悲惨了。

此外,不必要时不要使用 SELECT。
想一想。
如果你的表有几十个字段,但你只关心一两个,并且想将它们全部包含在索引中,那么索引不应该也和这几十个字段一样大吗?不仅浪费空间,而且查询时索引可能会变得太长并超过 7 6 7 字节限制(InnoDB 默认值),从而导致构建浪费。

所以覆盖索引是好的,但是你必须在正确的地方使用它们。
首先,你需要了解用户经常用来检查数据的字段,避免随意添加。
构建索引后,运行 EXPLAIN 以查看索引是否实际被使用。
不要仅仅听到 Extra 中的“索引用法”就欣喜若狂。
我当时就有这种失落感。
一开始我没有仔细阅读EXPLAIN,认为如果添加索引会更快。
但我发现查询计划包含一个using索引条件,我必须返回表,一切都无济于事。
教训,教训。

mysql使用全文索引实现大字段的模糊查询

说白了,在CentOS7 +MySQL5 .7 环境下使用InnoDB进行全文检索的核心就是正确配置ngram。
这个问题由于中文分词而变得复杂,但关键步骤有三个。
配置更改、索引修复以及使用适当的查询。

我们先来说说最重要的事情。
创建表时,您可以做的不仅仅是添加全文(内容)。
要专门指定 ngram 解析器,您应该使用 FULLTEXT(content_word) WITH PARSER ngram。
我们去年尝试过这个项目,如果不添加解析器就不可能搜索中文。
还有一点是需要在[mysqld]中添加两个参数:ft_min_word_len=1 和ngram_token_size=1 否则MySQL会报插件未启用的错误。
说实话,这很令人困惑。
去年我以为是版本问题。
还有另一个重要的细节。
构建索引后,您需要等待,直到看到类似“%ngram%”的变量。
确保启用 ngram_token_size 并使用 OPTIMIZE TABLE tbl_article_content 修复它。
大约有3 000级数据。
直接检查而不修理会花费两倍以上的时间。

我一开始以为中文分词功能是插件自带的,后来发现不对,不得不使用LOAD PLUGIN手动加载ngram插件。
还有一件事:查询时避免使用像 LIKE '%No more%' 这样的模糊匹配。
全文索引逐字匹配,因此使用 MATCH(content) AGAINST('No more')。
很多人不注意这一点。

我们建议您首先使用 INT AUTO_INCRMENT PRIMARY KEY 在article_id 上构建索引。
查找时使用LIMIT 1 0 OFFSET 0进行分页。
如果数据量很大,直接查找会超时。
您如何看待使用 ngram_token_size=2 点来获得更精细的单词粒度?