点击下方公众号「关注」和「星标」

回复“1024”获取独家整理的学习资料!

虽然你这列上建了索引,查询条件也是索引列,但最终执行计划没有走它的索引。下面是引起这种问题的几个关键点。

列与列对比

某个表中,有两列(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等。搜索公众号民工哥技术之路,回复“1024”,送你一份技术资源,还可查阅更多技术干货文章及面试题精选。

复合索引前导列区分大

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

select * from test where owner='sunyang';

数据类型的转换

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

select * from sunyang where id='123';

Connect By Level

使用connect by level时,不会走索引。

  • 谓词运算

我们在上面说,不能对索引列进行函数运算,这也包括加减乘除的谓词运算,这也会使索引失效。建立一个sunyang表,索引为id,看这个SQL:

select * from sunyang where id/2=:type_id;

这里很明显对索引列id进行了’/2’除二运算,这时候就会索引失效,这种情况应该改写为:

select * from sunyang where id=:type_id*2;

就可以使用索引了。推荐:从认识索引到理解索引「索引优化」

Vistual Index

先说明一下,虚拟索引的建立是否有用,需要看具体的执行计划,如果起作用就可以建一个,如果不起作用就算了。深入了解MySQL的索引

普通索引这么建:

create index idx_test_id on test(id);

虚拟索引Vistual Index这么建:

create index idx_test_id on test(id) nosegment;

做了一个实验,首先创建一个表:

CREATE TABLE test_1116(
id number,
a number
); CREATE INDEX idx_test_1116_id on test_1116(id);
CREATE INDEX idx_test_1116_a on test_1116(a)nosegment;

其中id为普通索引,a为虚拟索引。

在表中插入十万条数据

begin
for i in 1 .. 100000 loop insert into test_1116 values (i,i);
end loop;
commit;
end;

接着分别去执行下面的SQL看时间,由于在内网机做实验,图贴不出来,数据保证真实性。

select count(id) from test_1116;
--第一次耗时:0.061秒
--第二次耗时:0.016秒
select count(a) from test_1116;
--第一次耗时:0.031秒
--第二次耗时:0.016秒

因为在执行过一次后,oracle对结果集缓存了,所以第二次执行耗时不走索引,走内存就都一样了。可以看到在这种情况下,虚拟索引比普通索引快了一倍。

具体虚拟索引的使用细节,这里不再展开讨论。

Invisible Index

Invisible Index是oracle 11g提供的新功能,对优化器(还接到前面博客里讲到的CBO吗)不可见,我感觉这个功能更主要的是测试用,假如一个表上有那么多索引,一个一个去看执行计划调试就很慢了,这时候不如建一个对表和查询都没有影响的Invisible Index来进行调试,就显得很好了。

通过下面的语句来操作索引

alter index idx_test_id invisible;
alter index idx_test_id visible;

如果想让CBO看到Invisible Index,需要加入这句:

alter session set optimizer_use_invisible_indexes = true;

基本就这些了,有问题欢迎留言指出,共同进步!

作者:番茄发烧了

blog.csdn.net/bless2015/article/details/84134361

推荐阅读 点击标题可跳转

牛逼!下一代 Docker 镜像构建神器

Nginx 常用配置汇总!从入门到干活,足矣

大厂小厂都在用的 RAID 软件阵列技术,你不学吗?

求求你了!别瞎提交代码了,看人家 Git 提交规范那叫一个舒服!

超牛逼!这款轻量级性能监控系统真强大~

从 0 到 1 手把手教你制作酷炫可视化大屏

几种技巧,帮你提升接口查询速度

小试牛刀!Nginx 搭建静态资源服务器

Kafka是什么,主要应用在什么场景?

索引失效的场景有哪些?索引何时会失效?相关推荐

  1. mysql复合索引的应用场景_mysql复合索引(联合索引)的使用场景

    什么是联合索引? 联合索引又叫复合索引.对于复合索引:Mysql从左到右的使用索引中的字段,一个查询可以只使用索引中的一部份,但只能是最左侧部分.例如索引是key index (a,b,c). 可以支 ...

  2. MySQL索引优化:索引失效以及不适合建立索引的场景

    引言: 索引是有双面性的,合理的建立索引可以提高数据库的效率.但是如果没有合理的构建索引和使用索引,可能会导致索引失效或者影响数据库性能,本文主要讨论的是索引失效以及不适合建立索引的场景 结论:具体案 ...

  3. 阿里面试:索引失效的场景有哪些?索引何时会失效?

    作者 | 番茄发烧了 来源 | http://blog.csdn.net/bless2015/article/details/84134361 虽然你这列上建了索引,查询条件也是索引列,但最终执行计划 ...

  4. MySQL索引失效的场景

    1.like 以%开头,索引无效:当like前缀没有%,后缀有%时,索引有效. 2.数据库表数据量过小 如果表的数据量非常小,则MySQL可能不会使用索引,因为它认为全表扫描的代价更小. 3.or语句 ...

  5. mysql引用表无效列_Mysql使用索引可能失效的场景

    1.WHERE字句的查询条件里有不等于号(WHERE column!=-),MYSQL将无法使用索引 2.类似地,如果WHERE字句的查询条件里使用了函数(如:WHERE DAY(column)=-) ...

  6. oracle不适合建立索引的场景,Oracle 分区表中本地索引和全局索引的适用场景

    背景 分区表创建好了之后,如果需要最大化分区表的性能就需要结合索引的使用,分区表有两种索引:本地索引和全局索引.既然存在着两种的索引类型,相信存在即合理.既然存在就会有存在的原因,也就是在特定的场景中 ...

  7. go 类型 value 不支持索引_10分钟掌握PostgreSQL 5种索引的应用场景

    索引是增强数据库性能的常用方法.索引使得数据库在查找和检索数据库的特定行的时候比没有索引快的多.但索引也增加了整个数据库系统的开销,所以应该合理使用. PostgreSQL提供了几种索引类型:B-tr ...

  8. mysql防止索引崩溃_MySQL优化之避免索引失效的方法

    在上一篇文章中,通过分析执行计划的字段说明,大体说了一下索引优化过程中的一些注意点,那么如何才能避免索引失效呢?本篇文章将来讨论这个问题. 避免索引失效的常见方法 1.对于复合索引的使用,应按照索引建 ...

  9. mysql 加索引不起作用_mysql加索引及索引失效的情况

    前言:B+TREE索引的本质是多路绝对平衡查找树,磁盘指针,相当于书的目录,索引不是越多越好. 一:如何加索引 1.PRIMARY  KEY(主键索引) mysql>ALTER  TABLE   ...

最新文章

  1. 【ORACLE技术嘉年华PPT】MySQL压力测试经验
  2. php--理解PHP的依赖注入和laravel的服务容器
  3. zabbix监控搭建
  4. 数据结构--图 Graph
  5. 北京计算机一级2020,2020北京市一级计算机基础及MS Office应用考试在线自测试题库(不限设备,登陆即可做题)...
  6. oracle修改redo路径,oracle修改redo log files路径
  7. DB2 9 运用开拓(733 测验)认证指南,第 4 部门: 嵌入式 SQL 编程(4)
  8. 统计自然语言处理梳理一:分词、命名实体识别、词性标注
  9. 5款精美APP原型设计模板,触手可得
  10. telink 9xxx 系列V1.3开发板接线说明
  11. multi-key map passed in for ordered parameter sort
  12. Photoshop抠图(磁性套索工具及几个常用案例)
  13. 基于Bootstrap的下拉框多选 Bootstrap Multiselect 插件使用
  14. 关于微信支付签名错误的一些可能的解决方向
  15. 【妄言之言】我的2016--困境与选择
  16. matlab隐形眼镜类型预测,决策树预测隐形眼镜类型
  17. 计算机音乐念诗之王,小可儿《念诗之王》[FLAC/MP3-320K]
  18. 构件组装-总结与展望
  19. 气象NC扇形经纬网格转换成前端要求的等经纬网格
  20. C++通过Read函数读取文件

热门文章

  1. C#自学书籍全集C#自学英文原版书籍
  2. springboot使用阿里云全球物流快递查询实现根据物流单号实时查询
  3. 网易薄荷停服:他日山高水长,江湖再见
  4. 基于MFC实现电脑录屏小程序
  5. 【欧拉函数】 欧拉函数计算及打表
  6. python云服务器搭建教程_小白怎么搭建自己的个人博客网站?云服务+WordPress教程...
  7. 圈1到圈50打不出来,直接复制
  8. 关于服务器如何使用与安装screen,以及screen的一些方法!!
  9. 苹果电脑拷贝文件到u盘很慢_U盘防拷贝哪家比较好?哪个做得好?
  10. C语言编程可调电子钟设计,基于ZG211使用C语言编程的电子钟显示设计(最终版)...