索引下推
缩写为ICP,索引条件下推(ICP)是MySQL 5.6中的新特性,是在存储引擎层使用索引过滤数据的一种优化方式 。ICP可以减少存储引擎访问基表和MySQL服务器访问存储引擎的次数 。
例如:
我们需要查询姓名以javacode35开头,性别为1的记录的数量 。sql如下所示:
MySQL > select count(id)from test1a,其中name like 'javacode35% ',sex = 1;-| count(id)|-| 55556 |-集合中的1行(0.19秒)
流程:
用javacode35按名称索引检索第一条记录,并获取记录id 。
此记录R1是通过使用id从主键索引中找到的 。
判断R1的性别是否为1,然后重复上述操作,直到找到所有记录 。
在上面的过程中,需要取名字索引,返回表 。
如果采用ICP,我们可以这样做,创建一个(姓名,性别)的组合索引 。查询过程如下:
取(name,sex)索引用javacode35检索第一条记录,可以得到(name,sex,id),记录为R1 。
判断R1.sex是否为1,然后重复上述操作,直到找到所有记录 。
这个过程不需要返回表,整个条件可以通过索引的数据进行筛选,比上面的更快 。
数字使字符串类索引无效 。
mysql> insert into test1 (id,name,sex,email)值(4000001,' 1 ',1,' javacode 2018 @ 163 . com ');查询正常,1行受影响(0.00秒)MySQL > select * from test1 where name = ' 1 ';---| id | name | sex | email |--4000001 | 1 | 1 | javacode2018@163.com |--集合中的1行(0.00秒)MySQL > select * from test1 where name = 1;--| id | name | sex | email |--| 4000001 | 1 | 1 | javacode2018@163.com |-集合中的1行,65535个警告(3.30秒)
对于上面的三条sql,我们插入了一条记录 。
第二个查询很快,第三个查询用name和1比较 。名字有索引,名字是字符串类型 。用数字比较字符串时,字符串会被强制转换成数字再进行比较,所以第二次查询就变成了全表扫描,只能取出每一条数据,名字会被转换成数字再和1进行比较 。
比较数值型字段和字符串有什么影响?如下所示:
MySQL > select * from test1 where id = ' 4000000 ';--| id | name | sex | email |--| 4000000 | javacode 4000000 | 2 | javacode4000000@163.com |-set中的1行(0.00秒)MySQL > select * from test1其中id = 4000000--| id | name | sex | email |--| 4000000 | javacode 4000000 | 2 | javacode4000000@163.com |-集合中的一行(0.00秒)
id上有一个主键索引,id的类型为int 。如你所见,上面两个查询都非常快,可以正常使用索引快速检索,所以如果字段是数组类型,查询值是字符串还是数组都会被索引 。
函数使索引无效 。
mysql >从test1 a中选择a.name 1其中a.name = ' javacode1-| a . name 1 |-| 1 |-集合中的1行,1个警告(0.00秒)MySQL > select * from test1a where concat(a . name,' 1 ')= ' javacode 11 ';--| id | name | sex | email |--| 1 | javacode 1 | 1 | javacode1@163.com |-集合中的一行(2.88秒)
名字上有索引,上面的查询,第一个取索引,第二个不取,第二个使用函数后,名字所属的索引树无法快速定位到需要查找数据的页面,只能将所有页面的记录加载到内存中,用函数计算每个数据后再进行条件判断 。此时,索引是无效的,它变成了全表数据扫描 。
结论:使用函数查询,索引字段无效 。
运算符使索引无效 。
mysql> select * from test1 a其中id = 2-1;---| id | name | sex | email |--1 | javacode 1 | 1 | javacode1@163.com |--集合中的1行(0.00秒)MySQL > select * from test1a其中id 1 = 2;--| id | name | sex | email |--| 1 | javacode 1 | 1 | javacode1@163.com |-集合中的一行(2.41秒)
id上有一个主键索引,上面的查询,第一个取索引,第二个不取索引,第二个用运算符 。id所在的索引树无法快速定位要搜索的数据所在的页面,所以我们只能将所有页面的记录加载到内存中,然后计算每个数据的ID,再判断是否等于1 。此时,索引是无效的,它变成了全表数据扫描 。
推荐阅读
- 如何设置QQ交友验证问题
- 芥末酱的配方是什么
- 埃菲尔铁塔简笔画
- 义乌有什么好玩的地方
- 对虾和青虾的区别
- 如何设置qq空间全背景的封面
- 桂林有什么好玩的旅游景点
- 长沙有什么好玩的地方
- 如何设置QQ空间说说尾巴
- 汕头有什么好玩的景点
