oracle

一张5000万的表,里面有五个字段的主键索引,还有一个单独字段的索引,使用kettle进行插入/更新时,不走主键索引,一开始以为是字段类型不匹配,后面通过session,提取出sql,发现果然是不走主键索引,走了一个单列的索引。
主键主键:PK_RY_GERENJBXX (GERENBH, SENDSYSTEMID, JIGOUBM, JIUZHENKH, JIUZHENKLX)
普通索引: RY_GERENJBXX_JIGOUBM (JIGOUBM)

查看执行计划

left join 走索引吗 left join on不走索引_数据库

五个字段都是主键的字段,不用PK_RY_GERENJBXX,而使用RY_GERENJBXX_JIGOUBM ,很是奇怪;

尝试使用强制索引。

/*+index(t PK_RY_GERENJBXX)*/    --t是别名

left join 走索引吗 left join on不走索引_left join 走索引吗_02

果然,update速度非常的快,实际update也是如此,奇怪了,为什么不走主键的索引呢?通过以下查看原因。

1、字段类型不能直接不匹配,比如<>,like “%”、“_”开头的,in 多个字段的,数字类型=字符类型,或者经过计算、转换后再“=”的,不能进行直接与索引字段匹配的。
2、where条件顺序问题

经过测试,在kettle输入中添加tochar(),cast(),都没有生效,直接手动填入对应的字段类型都没有作用。
where条件顺序问题,经过测试,也不是这个,and之间的顺序,执行计划会自动调优解析的,除非是很旧的数据库版本。

ps:
以下索引会生效的,sql执行没有那么弱智
如:
in (‘A’) in一个字段的
like ‘A’ like 一个字段的
like ‘ABDC%’ like 前缀不变的,这种可能生效可能不生效,看基数,具体原因要看索引的基本原理了。

既然不是sql编写的问题,那么肯定是执行计划问题了。

为什么执行计划那么弱智呢?纳闷了,由于是在kettle上,不能使用强制索引,所以,进行数据库配置索引等方面调优了。
经过查找资料。

analyze table table_name compute statistics;
analyze table table_name compute statistics for all indexes;
analyze index index_name  compute statistics;
analyze index index _name compute statistics;

使用analyze 对表和索引进行重新统计。具体会统计哪些信息需要查看相关资料,总之analyze 统计的信息会对执行计划有影响。
由于表太大,直接使用analyze table table_name compute
直接执行超时了,尴尬了=_=||

然后,我直接开启了靶向打击,对这个可恶的索引进行analyze

analyze index RY_GERENJBXX_JIGOUBM compute statistics;

很快就执行好了,发现果然走主键索引了。

left join 走索引吗 left join on不走索引_sql_03

因为,通过analyze进行靶向打击后,执行计划开始认清了RY_GERENJBXX_JIGOUBM 的真正面目,知道了使用它执行会更慢。

然后我再对主键索引进行analyze

analyze index PK_RY_GERENJBXX  compute statistics;

结束。

总结:
1、如果不是使用kettle,没办法使用强制索引,项目经理安排太紧,我就直接使用强制索引,可能就错过了继续学习的机会。
2、了解sql执行的基本流程,拆分排查原因,无论是开发优化还是测试,还是高效的工作,都至关重要。这也是为什么基础、框架、架构的这么重要的原因。