mysql索引详解

索引7问

什么是索引?有什么作用?

索引就相当于一本书的目录,通过目录可以快速的找到对于的资源。
在数据库方面,查询一个表的时候有两种检索方式:

  • 第一种方式:全表扫描
  • 第二种方式:根据索引检索(效率很高)

索引为什么可以提高检索效率呢?

 其实最根本的原理是缩小了扫描的范围。

索引虽然可以提高检索效率,但是不能随意的添加索引,因为索引也是
数据库中的对象,也需要数据库不断的维护。是有维护成本的
。比如,表
中的数据经常被修改,这样就不适合添加索引。因为数据一旦被修改,索引
需要重新排序,进行维护。

怎么创建索引?怎么删除索引对象。

   创建索引对象:
   create index 索引名称 on 表名(字段名);
   删除索引对象:
   drop index 索引名称 on 表名;
   oracle 数据库 中 drop index 索引名称; 也可以使用

什么时候考虑给字段添加索引?(满足什么条件)

  • 数据量庞大(根据具体情况分析)
  • 该字段很少的DML操作。(因为字段进行修改操作,索引也需要维护)
  • 该字段经常出现在where子句中。(经常根据哪个字段查询,就将它放到索引中)

注意
主键和具有unique约束的字段自动会添加索引。
在数据表查询中,根据主键查询效率较高。尽量根据主键检索。

索引的分类?

  • 单一索引:给单个字段添加索引
  • 复合索引:给多个字段联合起来添加一个索引
  • 主键索引:主键上会自动添加索引
  • 唯一键索引:有unique 约束的字段上会字段添加索引

索引什么时候失效?

模糊查询的时候,第一个通配符使用的是%,这个时候索引会失效
eg:

select ename from emp where ename like "%A%"

列与列对比

某个表中,有两列(id和c_id)都建了单独索引,下面这种查询条件不会走索引

select * from test where id=c_id;

存在NULL值条件

我们在设计数据库表时,应该尽力避免NULL值出现,如果非要不可避免的要出现NULL值,也要给一个DEFAULT值,数值型可以给0、-1之类的, 字符串有时候给空串有问题,就给一个空格或其他。如果索引列是可空的,是不会给其建索引的,索引值是少于表的count(*)值的,所以这种情况下,执行计划自然就去扫描全表了。

select * from test where id is not null;

NOT条件

我们知道建立索引时,给每一个索引列建立一个条目,如果查询条件为等值或范围查询时,索引可以根据查询条件去找对应的条目。反过来当查询条件为非时,索引定位就困难了,执行计划此时可能更倾向于全表扫描,这类的查询条件有:<>、NOT、in、not exists

select * from test where id<>500;
select * from test where id in (1,2,3,4,5);
select * from test where not in (6,7,8,9,0);
select * from test where not exists (select 1 from test_02 where test_02.id=test.id)

LIKE通配符

当使用模糊搜索时,尽量采用后置的通配符,例如:name||’%’,因为走索引时,其会从前去匹配索引列,这时候是可以找到的,如果采用前匹配,那么查索引就会很麻烦,比如查询所有姓张的人,就可以去搜索’张%’。相反如果你查询所有叫‘明’的人,那么只能是%明。这时候索引如何定位呢?前匹配的情况下,执行计划会更倾向于选择全表扫描。后匹配可以走INDEX RANGE SCAN。
所以业务设计的时候,尽量考虑到模糊搜索的问题,要更多的使用后置通配符。

select * from test where name like||'%';

条件上包括函数

查询条件上尽量不要对索引列使用函数,比如下面这个SQL

select * from test where upper(name)='SUNYANG';

这样是不会走索引的,因为索引在建立时会和计算后可能不同,无法定位到索引。但如果查询条件不是对索引列进行计算,那么依然可以走索引。比如

select * from test where name=upper('sunyang');
--INDEX RANGE SCAN

这样的函数还有:to_char、to_date、to_number、trunc等

复合索引前导列区分大

当复合索引前导列区分小的时候,我们有INDEX SKIP SCAN,当前导列区分度大,且查后导列的时候,前导列的分裂会非常耗资源,执行计划想,还不如全表扫描来的快,然后就索引失效了。

select * from test where owner='sunyang';

数据类型的转换

当查询条件存在隐式转换时,索引会失效。比如在数据库里id存的number类型,但是在查询时,却用了下面的形式:

select * from sunyang where id='123';

简单描述索引的实现原理?

通过B Tree 缩小扫描范围,底层索引进行了排序,分区,索引会携带数据在表中的"物理地址",最终通过索引检索到数据之后,获取到关联的物理地址,通过物理地址定位表中的数据,效率是最高的。

 select  ename from emp where ='SMITH'

通过索引转换为:

  select  ename from emp where ='0x3';

原理解析图

索引

参考文献

索引失效的情况有哪些?索引何时会失效?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

piepis

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值