MySQL全文索引、联合索引、like查询、json查询速度大比拼
查询背景
有一个表tmp_test_course大概有10万条记录,然后有个json字段叫outline,存了一对多关系(保存了多个编码,例如jy1577683381775)
我们需要在这10万条数据中检索特定类型的数据,目标总数据量:2931条
SELECT COUNT(*) FROM tmp_test_course WHERE `type`=5 AND del=2 AND is_leaf=1

我们在限定为上面类型的同时,还得包含下面任意一个编码(也就是OR查询)
jy1577683381775
jy1577683380808
jy1577683379178
jy1577683378676
jy1577683377617
jy1577683376672
jy1577683375903
jy1578385720787
jy1499916986208
jy1499917112460
jy1499917093400
jy1499917335579
jy1499917334770
jy1499917333339
jy1499917331557
jy1499917330833
jy1499917329615
jy1499917328496
jy1576922006950
jy1499916993558
jy1499916992308
jy1499917003454
jy1499917002952
下面分别列出4种方式查询outline字段,给出相应的查询时间和扫描行数
一、like查询
耗时248毫秒
SELECT * FROM tmp_test_course
WHERE `type`=5 AND del=2 AND is_leaf=1
AND (
outline like '%jy1577683381775%'
OR outline like '%jy1577683380808%'
OR outline like '%jy1577683379178%'
OR outline like '%jy1577683378676%'
OR outline like '%jy1577683377617%'
OR outline like '%jy1577683376672%'
OR outline like '%jy1577683375903%'
OR outline like '%jy1578385720787%'
OR outline like '%jy1499916986208%'
OR outline like '%jy1499917112460%'
OR outline like '%jy1499917093400%'
OR outline like '%jy1499917335579%'
OR outline like '%jy1499917334770%'
OR outline like '%jy1499917333339%'
OR outline like '%jy1499917331557%'
OR outline like '%jy1499917330833%'
OR outline like '%jy1499917329615%'
OR outline like '%jy1499917328496%'
OR outline like '%jy1576922006950%'
OR outline like '%jy1499916993558%'
OR outline like '%jy1499916992308%'
OR outline like '%jy1499917003454%'
OR outline like '%jy1499917002952%'
)

EXPLAIN分析结果如下,全表扫描

二、json函数查询
使用函数JSON_SEARCH,更多函数请查看MySQL官方文档
可以看到,查询耗时196毫秒,速度稍微快了一点
SELECT * FROM tmp_test_course
WHERE `type`=5 AND del=2 AND is_leaf=1
AND
(
JSON_SEARCH(outline, 'one', 'jy1577683381775') IS NOT NULL OR
JSON_SEARCH(outline, 'one', 'jy1577683380808') IS NOT NULL OR
JSON_SEARCH(outline, 'one', 'jy1577683379178') IS NOT NULL OR
JSON_SEARCH(outline, 'one', 'jy1577683378676') IS NOT NULL OR
JSON_SEARCH(outline, 'one', 'jy1577683377617') IS NOT NULL OR
JSON_SEARCH(outline, 'one', 'jy1577683376672') IS NOT NULL OR
JSON_SEARCH(outline, 'one', 'jy1577683375903') IS NOT NULL OR
JSON_SEARCH(outline, 'one', 'jy1578385720787') IS NOT NULL OR
JSON_SEARCH(outline, 'one', 'jy1499916986208') IS NOT NULL OR
JSON_SEARCH(outline, 'one', 'jy1499917112460') IS NOT NULL OR
JSON_SEARCH(outline, 'one', 'jy1499917093400') IS NOT NULL OR
JSON_SEARCH(outline, 'one', 'jy1499917335579') IS NOT NULL OR
JSON_SEARCH(outline, 'one', 'jy1499917334770') IS NOT NULL OR
JSON_SEARCH(outline, 'one', 'jy1499917333339') IS NOT NULL OR
JSON_SEARCH(outline, 'one', 'jy1499917331557') IS NOT NULL OR
JSON_SEARCH(outline, 'one', 'jy1499917330833') IS NOT NULL OR
JSON_SEARCH(outline, 'one', 'jy1499917329615') IS NOT NULL OR
JSON_SEARCH(outline, 'one', 'jy1499917328496') IS NOT NULL OR
JSON_SEARCH(outline, 'one', 'jy1576922006950') IS NOT NULL OR
JSON_SEARCH(outline, 'one', 'jy1499916993558') IS NOT NULL OR
JSON_SEARCH(outline, 'one', 'jy1499916992308') IS NOT NULL OR
JSON_SEARCH(outline, 'one', 'jy1499917003454') IS NOT NULL OR
JSON_SEARCH(outline, 'one', 'jy1499917002952') IS NOT NULL
)

EXPLAIN分析结果如下,还是全表扫描

三、联合索引查询
下面为该表建立一个联合索引(本来想建一个type-del-is_leaf-outline的索引,但是outline字段太长限制,所以只加type-del-is_leaf的联合索引
ALTER TABLE tmp_test_course ADD KEY `type-del-is_leaf` (`type`,`del`,`is_leaf`)
加入索引后再执行like和json查询,明显提速。
like执行用了136毫秒,json查询用了82.6毫秒,由此可见针对json类型使用json函数查询比like快


EXPLAIN分析结果如下,两者查询扫描的行数都限定在了2931行


四、全文索引查询
因为全文索引只支持CHAR、VARCHAR和TEXT,我们需要把JSON字段定义改一下
ALTER TABLE tmp_test_course MODIFY `outline` VARCHAR(1024) NOT NULL DEFAULT '[]'
添加全文索引
ALTER TABLE tmp_test_course ADD FULLTEXT INDEX outline (outline);
现在再来用全文索引进行检索
SELECT * FROM tmp_test_course
WHERE `type`=5 AND del=2 AND is_leaf=1
AND
MATCH(outline) AGAINST ('jy1577683381775 jy1577683380808 jy1577683379178 jy1577683378676 jy1577683377617 jy1577683376672 jy1577683375903 jy1578385720787 jy1499916986208 jy1499917112460 jy1499917093400 jy1499917335579 jy1499917334770 jy1499917333339 jy1499917331557 jy1499917330833 jy1499917329615 jy1499917328496 jy1576922006950 jy1499916993558 jy1499916992308 jy1499917003454 jy1499917002952')
耗时11.6毫秒,速度提升极其明显,可见全文索引的牛逼。

EXPLAIN分析结果如下,显示只扫描了一行

结论
以下是4种情况的执行结果
全文索引: 11.6ms
联合索引:82.6ms(json)、136ms(like)
json函数查询:196ms
like查询: 248ms
结论:全文索引 > 联合索引 > json函数查询 > like查询
数据量越大,全文索引速度越明显,就10万的量,查询速度大概比直接查询快了20倍左右,如果是百万或千万级别的表,提升差距会更加大,所以有条件还是老老实实用全文索引吧
MySQL全文索引、联合索引、like查询、json查询速度大比拼的更多相关文章
- MySQL全文索引 FULLTEXT索引和like的区别
1.概要 InnoDB引擎对FULLTEXT索引的支持是MySQL5.6新引入的特性,之前只有MyISAM引擎支持FULLTEXT索引.对于FULLTEXT索引的内容可以使用MATCH()-AGAIN ...
- Mysql 创建联合索引注意事项
当一个表有多条索引可走时, Mysql 根据查询语句的成本来选择走哪条索引, 联合索引的话, 它往往计算的是第一个字段(最左边那个), 这样往往会走错索引. 如: 索引Index_1(Crea ...
- Mysql中联合索引的最左匹配原则
在Mysql建立多列索引(联合索引)有最左前缀的原则,即最左优先. 如果我们建立了一个2列的联合索引(col1,col2),实际上已经建立了两个联合索引(col1).(col1,col2); 如果有一 ...
- 一个案例彻底弄懂如何正确使用 mysql inndb 联合索引
有一个业务是查询最新审核的5条数据 SELECT `id`, `title` FROM `th_content` WHERE `audit_time` < 1541984478 AND `sta ...
- Mysql中联合索引的最左匹配原则(百度)
创建联合索引时列的选择原则 经常用的列优先(最左匹配原则) 离散度高的列优先(离散度高原则) 宽度小的列优先(最少空间原则) 在Mysql建立多列索引(联合索引)有最左前缀的原则,即最左优先.如果我们 ...
- MySQL之联合索引
以 index(a, b, c) 为例: 语句 发挥作用的索引 记忆方法(以三块板子过河记忆, 顺序很重要) WHERE a=3 只用到了a列 只走了a板子 WHERE a=3 AND b=5 使用了 ...
- mysql的联合索引的误解
https://www.zhihu.com/question/36996520 之前对于联合索引有一个误区, 假设 name,age为一个联合索引 5条索引记录 a 10 b 5 c 12 c 15 ...
- mysql使用联合索引提示字符长度超限制解决办法
mysql在创建数据库的时候,字符集设置的不是utf8而是utf9mb4,在导入sql脚本的时候,发现提示如下错误: 从上图中,我们可以看出,使用的是innodb及字符集.错误提示是长度太长了 ...
- mysql选择联合索引还是单索引?索引列应该使用哪一个最有效?深入測试探讨
先建表 CREATE TABLE `menu_employee` ( `Id` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增主键,无实际意义', `emplo ...
- mysql的联合,连接,子查询
随机推荐
- python3搭建Django项目
1.本次安装的python3.7版本,可前往官网下载,这里的安装不作多余介绍 2.安装虚拟环境 第一种:virtualenv:用于创建虚拟环境,实现项目之间的环境隔离,解决项目中存在的版本冲突问题 w ...
- “Your build settings specify a provisioning profile with the UUID “”, however, no such provisioning profile was found”
解决方法: 终端命令行输入下面语句,删除所有的Profilescd ~/Library/MobileDevice/Provisioning\ Profiles/rm *.mobileprovision
- python IO非阻塞模型
server端 import socket sk = socket.socket() sk.bind(('127.0.0.1', 8010)) sk.setblocking(False) # sk.l ...
- maven install 报错 Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.12.4:test
pom文件引入以下依赖 <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId> ...
- 个人任务Day3
昨日成果: 学习有关java的网络爬虫知识. 今日任务: 向数据库中完善数据,并写出选择查看团队博客的界面.
- 《Sequence Models》课堂笔记
Lesson 5 Sequence Models 这篇文章其实是 Coursera 上吴恩达老师的深度学习专业课程的第五门课程的课程笔记. 参考了其他人的笔记继续归纳的. 符号定义 假如我们想要建立一 ...
- 手把手写一个基于Spring Boot框架下的参数校验组件(JSR-303)
前言 之前参与的新开放平台研发的过程中,由于不同的接口需要对不同的入参进行校验,这就涉及到通用参数的校验封装,如果不进行封装,那么写出来的校验代码将会风格不统一.校验工具类不一致.维护风险高等其它因素 ...
- python接口自动化测试 - openpyxl基本使用
前言 当你做接口自动化测试时,测试用例逐渐变多情况下,如果所有测试用例都通过代码管理将会使得代码十分臃肿,而且维护成本会很高: 所以我们一般会通过Excel去管理所有的测试用例,而openpyxl库提 ...
- allegro设置内存分配器的一个坑
看过<游戏引擎架构>后我开始对内存的分配问题关注,一直想用内存分配器来管理游戏的内存.前两天发现了有许多第三方内存分配器可以用.最后挑中了nedmalloc,这个库也是ogre所使用的,测 ...
- js原型链和原型链的继承
每一个对象都有一个“_proto_”指针,指向实例化该对象的构造函数的原型对象,当该对象没有你想拿到的属性时,解释器会顺着指针不断向上找. 每一个构造你函数都有一个“prototype”属性,指向该构 ...