朝代:先秦作者:佚名出自:网络整理更新时间:2023-07-05

一、SQL无法走索引的情况及解决思路

因为数据库优化器不够智能,或者一些逻辑原因,导致SQL在比较适合走索引的情况下却无法正确利用索引。这时候,除了给数据库需要的统计信息之外,SQL语句本身还必须要给优化器足够多的额外有效信息,帮助优化器能够选择更好的执行计划。要让优化器正确选择需要的索引,要考虑两点:

说明:这里说的走不了索引,是指走不了正常的RANGE SCAN,非(FAST) FULL INDEX SCAN。

SQL无法走索引常见的有如下8种情况:

统计信息不准确索引列的值允许为NULL谓词使用了不等于(<>, !=)LIKE前通配或全通配的查询索引列使用了函数、数学运算、其它表达式等使用了隐式类型转换查询转换失败其它语句逻辑原因

第一、二种情况在现实中比较常见,解决办法也相对比较简单,下面就不再作详细展开了。

谓词使用了不等于(<>,!=),走不了索引

解决方法:

如果不等条件之外的值不多,而且是确定的,可以改为等值或IN查询,比如status状态字段一般值类别很少;如果不等条件之外的值很多,可以改为“> OR <”的形式,当然第2种方法包含了方法1。

举个例子,先构建测试场景:

SQL无法走索引的情况及解决思路

谓词使用<>,无法利用索引:

索引不能执行的操作_索引处于不可用状态_sql创建索引语句

SQL无法走索引的情况及解决思路

将<>改写为OR连接后,能够正确使用索引,走OR扩展:

SQL无法走索引的情况及解决思路

如果业务允许,改写为下列语句也是走索引的,不再演示。

SELECT * FROM t WHERE t.NAME IN (‘ORADB1′,’ORADB2′,’ORADB3’);

LIKE前通配或全通配的查询,走不了索引

解决方法,有如下三种:

(1)根据业务需求,是否可以把前通配去掉

原来全通配,无法走索引:

SQL无法走索引的情况及解决思路

把前通配去掉,改为后通配,可以正常使用索引:

SQL无法走索引的情况及解决思路

索引不能执行的操作_索引处于不可用状态_sql创建索引语句

(2)和此LIKE一样的前通配或全通配的SQL有很多,此谓词的LIKE变化不大?如果是,考虑建立函数索引,否则对于全通配问题最好办法就是全文索引。

创建instr函数索引:

SQL无法走索引的情况及解决思路

(3)如果只是前通配,可以使用reverse函数索引(不是翻转键索引)

原始语句:

SELECT * FROM t WHERE t.NAME LIKE ‘%ORADB1’;

创建reverse函数索引,并改写语句,注意查找值要倒序:

SQL无法走索引的情况及解决思路

注意:如果通配查询的是中文,要注意使用REVERSE翻转条件值,因为REVERSE内部会按字节翻转的,正确写法如:

SELECT * FROM t WHERE REVERSE(t.name) LIKE REVERSE(‘数据’)||’%’;

否则查询出来的数据不对,将可能影响到业务的正常运行。

索引列使用了函数、数学运算、其他表达式等sql创建索引语句,走不了索引

sql创建索引语句_索引不能执行的操作_索引处于不可用状态

解决方法:去掉对索引列的相关运算,保持索引列纯净。

目前优化器对一些数学运算,还无法做很好的消除动作,所以对于索引列应该尽量保持纯净,否则可能无法用上正确的索引。

举例:

SQL无法走索引的情况及解决思路

把语句的条件改写一下,将运算去掉:

SQL无法走索引的情况及解决思路

以上例子只是简单的数学运算,可能的运算还有和其他列运算,比如where ID+ext_col…

记住一个原则:尽量保持索引列纯净。

使用了隐式类型转换,走不了索引

解决方法:必须避免隐式类型转换,全部要求显式类型转换(非索引列),且避免对索引列进行类型转换(有函数索引除外)。如果类型不一致,不管是否发生自动类型转换,谓词的右值应该显式转换为与索引列保持一致(对于非索引列的运算也应该如此)。

举例:

SQL无法走索引的情况及解决思路

索引不能执行的操作_索引处于不可用状态_sql创建索引语句

SQL无法走索引的情况及解决思路

从以上两次查询对比来看,第一次查询发生了类型转换,可以通过执行计划中的谓词信息获知。通过分析发现,X因为是VARCHAR2,优先级比数值类型低,遇到数值类型,会TO_NUMBER隐式转换,所以索引失效。第二次查询,通过传入与索引列类型一致的字符串后,得以解决。

查询转换失败,走不了索引

查询转换是非常复杂的过程,ORACLE CBO的查询转换有好几十种,比如CVM :complex view merging ,SU:subquery unnest, JPPD:JOIN PREDICATE PUSH DOWN等(在10053文件里都可以看到)。如果查询转换失败,那么必将影响后续优化器的一些操作,比如JPPD中JOIN谓词无法推入到视图中,那么很可能视图就无法走索引了。而且,查询转换有很多BUG,触发BUG需要找到原因,比如设置隐含参数、fix control等,或者改写SQL绕过BUG。如下例所示:

SQL无法走索引的情况及解决思路

其中AB_XRTOFFREC_201703是UNION ALL查询组成的视图,这个查询在10.2.0.4上很正常,升级到11.2.0.4后执行计划显示不走索引,性能非常差。

在10g中的执行计划:

SQL无法走索引的情况及解决思路

在11g中的错误执行计划:

SQL无法走索引的情况及解决思路

通过收集统计信息都无效,将优化器降级到10.2.0.4即有效。很显然,这是引入了BUG或者新的限制。一旦遇到这种是BUG或限制导致的,可以通过10053跟踪文件或者SQLT来进行分析。对于这条语句无法走JPPD查询转换,在10053中就可以找到原因:

SQL无法走索引的情况及解决思路

sql创建索引语句_索引处于不可用状态_索引不能执行的操作

然后在MOS中查看得知是BUG:9380298,默认开关关闭。

SQL无法走索引的情况及解决思路

ORACLE针对这样的查询,为了防止遇到笛卡尔积,默认把修复BUG的补丁关闭了。显然通过设置_fix_control参数打开9380298 fix即可。

语句逻辑问题,导致优化器选择不了索引

举一个典型的例子,先准备测试表,并在其上创建一个组合索引:

SQL无法走索引的情况及解决思路

查询需求:查找创建时间是2013年的,并且最后ddl时间比创建时间大1天以上的对象。

SQL无法走索引的情况及解决思路

这个索引是组合索引,上面的语句对前导列进行了运行,也不符合走index skip scan的条件sql创建索引语句,所以,走FULL TABLE SCAN。那么是否可以通过逻辑改写走索引呢,基于保持索引列纯净的原则,将create_date移到右边,语句如下:

SQL无法走索引的情况及解决思路

改写后发现,还是没有走索引,因为Oracle认为前导列右边的created不固定,无法从指定索引处查找。通过分析得知,Oracle谓词传递有一定限制,create_date+1无法做谓词传递给last_ddl_time。再次改写:

SQL无法走索引的情况及解决思路

佚名资料

SQL无法走索引的情况及解决思路作者佚名

佚名不是没有姓名的人,而是作者没有署名,或是由于时间久远等原因作者的真实姓名查无根据,或者根本就无法知道作者是谁。也有的是由于集体创作或是劳动人民从很久远的时候就流传下来的作品,这样的作品的作者就被标作&l... 查看详情>>

佚名古诗词作品: 《涉江采芙蓉》《赵威后问齐使》《范雎说秦王》《召公谏厉王弭谤》《公子重耳对秦客》《有子之言似夫子》《明月何皎皎》《庄子与惠子游于濠梁》《九辩》《闯王·朝求升,暮求合

SQL无法走索引的情况及解决思路的意思

SQL无法走索引的情况及解决思路相关诗句

  • 古诗《涉江采芙蓉 - - 佚名 - - 《涉江采芙蓉》作者为先秦诗人佚名,古诗《涉江采芙蓉》全文如下:涉江采芙蓉,兰泽多芳草。采之欲遗谁,所思在远道。还顾望旧乡,长路漫浩浩。同心而离居,忧伤以终老。
  • 古诗《明月何皎皎 - - 佚名 - - 明月何皎皎,照我罗床帏。


    忧愁不能寐,揽衣起徘徊。


    客行虽云乐,不如早旋归。


    出户独彷徨,愁思当告谁。


    引领还入房,泪下沾裳衣。
  • 古诗《九辩 - - 佚名 - - 《九辩》作者为先秦诗人佚名,古诗《九辩》全文如下:悲哉,秋之为气也!萧瑟兮草木摇落而变衰。憭栗兮若在远行,登山临水兮送将归。泬漻兮天高而气清,寂寥兮收潦而水清。憯
  • 古诗《闯王·朝求升,暮求合 - - 佚名 - - 《闯王·朝求升,暮求合》作者为先秦诗人佚名,古诗《闯王·朝求升,暮求合》全文如下:朝求升,暮求合,近来贫汉难存活。早早开门拜闯王,管教大小都欢悦。杀牛羊,备酒浆,开了城
  • 古诗《去者日以疏 - - 佚名 - - 《去者日以疏》作者为先秦诗人佚名,古诗《去者日以疏》全文如下:去者日以疏,生者日已亲。出郭门直视,但见丘与坟。古墓犁为田,松柏摧为薪。白杨多悲风,萧萧愁杀人。思还
  • 古诗《冉冉孤生竹 - - 佚名 - - 《冉冉孤生竹》作者为先秦诗人佚名,古诗《冉冉孤生竹》全文如下:冉冉孤生竹,结根泰山阿。与君为新婚,菟丝附女萝。菟丝生有时,夫妇会有宜。千里远结婚,悠悠隔山陂。思君
  • 古诗《孟冬寒气至 - - 佚名 - - 《孟冬寒气至》作者为先秦诗人佚名,古诗《孟冬寒气至》全文如下:孟冬寒气至,北风何惨栗。愁多知夜长,仰观众星列。三五明月满,四五蟾兔缺。客从远方来,遗我一书札。上言
  • 古诗《今日良宴会 - - 佚名 - - 《今日良宴会》作者为先秦诗人佚名,古诗《今日良宴会》全文如下:今日良宴会,欢乐难具陈。弹筝奋逸响,新声妙入神。令德唱高言,识曲听其真。齐心同所愿,含意俱未申。人生
  • 古诗《孺子歌 - - 佚名 - - 《孺子歌》作者为先秦诗人佚名,古诗《孺子歌》全文如下:沧浪之水清兮,可以濯我缨。沧浪之水浊兮,可以濯我足。
  • 古诗《客从远方来 - - 佚名 - - 《客从远方来》作者为先秦诗人佚名,古诗《客从远方来》全文如下:客从远方来,遗我一端绮。相去万余里,故人心尚尔。文彩双鸳鸯,裁为合欢被。著以长相思,缘以结不解。以胶
  • 古诗《庭中有奇树 - - 佚名 - - 《庭中有奇树》作者为先秦诗人佚名,古诗《庭中有奇树》全文如下:庭中有奇树,绿叶发华滋。攀条折其荣,将以遗所思。馨香盈怀袖,路远莫致之。此物何足贵,但感别经时。
  • 古诗《驱车上东门 - - 佚名 - - 《驱车上东门》作者为先秦诗人佚名,古诗《驱车上东门》全文如下:驱车上东门,遥望郭北墓。白杨何萧萧,松柏夹广路。下有陈死人,杳杳即长暮。潜寐黄泉下,千载永不寤。浩浩
  • 古诗《明月皎夜光 - - 佚名 - - 《明月皎夜光》作者为先秦诗人佚名,古诗《明月皎夜光》全文如下:明月皎夜光,促织鸣东壁。玉衡指孟冬,众星何历历。白露沾野草,时节忽复易。秋蝉鸣树间,玄鸟逝安适。昔我
  • 古诗《青青陵上柏 - - 佚名 - - 《青青陵上柏》作者为先秦诗人佚名,古诗《青青陵上柏》全文如下:青青陵上柏,磊磊涧中石。人生天地间,忽如远行客。斗酒相娱乐,聊厚不为薄。驱车策驽马,游戏宛与洛。洛中
  • 古诗《赓歌·股肱喜哉 - - 佚名 - - 《赓歌·股肱喜哉》作者为先秦诗人佚名,古诗《赓歌·股肱喜哉》全文如下:股肱喜哉。元首起哉。百工熙哉。元首明哉。股肱良哉。庶事康哉。元首丛脞哉。股肱惰哉。万
  • 古诗《采薇歌 - - 佚名 - - 《采薇歌》作者为先秦诗人佚名,古诗《采薇歌》全文如下:登彼西山兮,采其薇矣。以暴易暴兮,不知其非矣。神农虞夏忽焉没兮,我适安归矣。于嗟徂兮,命之衰矣。
  • 古诗《生年不满百 - - 佚名 - - 《生年不满百》作者为先秦诗人佚名,古诗《生年不满百》全文如下:生年不满百,常怀千岁忧。昼短苦夜长,何不秉烛游。为乐当及时,何能待来兹。愚者爱惜费,但为後世嗤。仙人
  • 古诗《迢迢牵牛星 - - 佚名 - - 《迢迢牵牛星》作者为先秦诗人佚名,古诗《迢迢牵牛星》全文如下:迢迢牵牛星,皎皎河汉女。纤纤擢素手,札札弄机杼。终日不成章,泣涕零如雨。河汉清且浅,相去复几许。盈盈
  • 古诗《凛凛岁云暮 - - 佚名 - - 《凛凛岁云暮》作者为先秦诗人佚名,古诗《凛凛岁云暮》全文如下:凛凛岁云暮,蝼蛄夕鸣悲。凉风率已厉,游子寒无衣。锦衾遗洛浦,同袍与我违。独宿累长夜,梦想见容辉。良人
  • 古诗《东城高且长 - - 佚名 - - 《东城高且长》作者为先秦诗人佚名,古诗《东城高且长》全文如下:东城高且长,逶迤自相属。回风动地起,秋草萋已绿。四时更变化,岁暮一何速。晨风怀苦心,蟋蟀伤局促。荡涤

佚名的名句