首页 > 数据库 >Oracle Hint "index_combine"对于like的局限性

Oracle Hint "index_combine"对于like的局限性

时间:2024-05-10 16:00:10浏览次数:22  
标签:index 00 OBJECT like ZKM Hint 00.01 NAME

 

Oracle Hint "index_combine"对于like的局限性

 

数据库版本:11.2.0.4.0

今天遇到1条问题SQL,优化遇到一点问题,SQL文本大概如下:

其中,col2和col3存在索引的且选择性都很高,col1的业务特性是只有两个值选择性低没有也不适合建Btree索引。

导致每次执行都是全表扫描,统计发现这条SQL每半小时执行次数大概在1200次左右。

select * from t
where t.col1='1'
and ( instr(t.col2, :1) > 0 or t.col3 = :2 )
order by t.create_time desc;

 

优化思路是将  instr(t.col2, :1) > 0  改为 t.col2 like '%'||:1||'%' ,之后让col2和col3对应索引做位图布尔运算,这样就能够有效避免全表扫描。

但是index_combine无法生效,研究发现index_combine不支持索引字段在谓词条件中使用了like '%%'的形式。。

 

这里可以创建测试样例表和样例SQL做说明。

create table zkm as select * from dba_objects;
create index idx_do_owner on zkm(owner);      
create index idx_do_object_name on zkm(object_name);

 

比如下边的第一条SQL(Hint强制index_combine)和执行计划,

以及第二条相同SQL但是Hint不同,单独like '%%'使用索引是没问题的。

select /*+ index_combine(zkm idx_do_owner idx_do_object_name) */ * from zkm                                         select /*+ index(zkm idx_do_object_name) */ * from zkm 
where owner='ZKM' and object_name like '%ZKM%';                                                                     where owner='ZKM' and object_name like '%ZKM%';
                                                                                                                    
Plan hash value: 301967187                                                                                          Plan hash value: 2326426975
                                                                                                                    
---------------------------------------------------------------------------------------------------------------     ---------------------------------------------------------------------------------------------------------------------
| Id  | Operation                   | Name         | Starts | E-Rows | A-Rows |   A-Time   | Buffers | Reads  |     | Id  | Operation                   | Name               | Starts | E-Rows | A-Rows |   A-Time   | Buffers | Reads  |
---------------------------------------------------------------------------------------------------------------     ---------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |              |      1 |        |      1 |00:00:00.01 |       6 |      2 |     |   0 | SELECT STATEMENT            |                    |      1 |        |      1 |00:00:00.05 |     242 |    178 |
|*  1 |  TABLE ACCESS BY INDEX ROWID| ZKM          |      1 |      1 |      1 |00:00:00.01 |       6 |      2 |     |*  1 |  TABLE ACCESS BY INDEX ROWID| ZKM                |      1 |      1 |      1 |00:00:00.05 |     242 |    178 |
|*  2 |   INDEX RANGE SCAN          | IDX_DO_OWNER |      1 |      9 |      3 |00:00:00.01 |       3 |      2 |     |*  2 |   INDEX FULL SCAN           | IDX_DO_OBJECT_NAME |      1 |   2821 |      3 |00:00:00.05 |     239 |    178 |
---------------------------------------------------------------------------------------------------------------     ---------------------------------------------------------------------------------------------------------------------
                                                                                                                    
Predicate Information (identified by operation id):                                                                 Predicate Information (identified by operation id):
---------------------------------------------------                                                                 ---------------------------------------------------
                                                                                                                    
   1 - filter(("OBJECT_NAME" IS NOT NULL AND "OBJECT_NAME" LIKE '%ZKM%'))                                              1 - filter("OWNER"='ZKM')
   2 - access("OWNER"='ZKM')                                                                                           2 - filter(("OBJECT_NAME" IS NOT NULL AND "OBJECT_NAME" LIKE '%ZKM%'))

 

 

 

 

但是支持like 'x%'的形式是没问题的。

select /*+ index_combine(zkm idx_do_owner idx_do_object_name) */ * from zkm                                                                         select /*+ index_combine(zkm idx_do_owner idx_do_object_name) */ * from zkm
where owner='ZKM' and object_name like 'ZKM%';                                                                                                      where owner='ZKM' or object_name like 'ZKM%';
                                                                                                                                                    
Plan hash value: 98540114                                                                                                                           Plan hash value: 4263379613
                                                                                                                                                    
--------------------------------------------------------------------------------------------------------------------------------------------        -------------------------------------------------------------------------------------------------------------
| Id  | Operation                        | Name               | Starts | E-Rows | A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |        | Id  | Operation                    | Name               | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
--------------------------------------------------------------------------------------------------------------------------------------------        -------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                 |                    |      1 |        |      1 |00:00:00.01 |       5 |       |       |          |        |   0 | SELECT STATEMENT             |                    |      1 |        |      5 |00:00:00.01 |      11 |
|   1 |  TABLE ACCESS BY INDEX ROWID     | ZKM                |      1 |     28 |      1 |00:00:00.01 |       5 |       |       |          |        |   1 |  CONCATENATION               |                    |      1 |        |      5 |00:00:00.01 |      11 |
|   2 |   BITMAP CONVERSION TO ROWIDS    |                    |      1 |        |      1 |00:00:00.01 |       4 |       |       |          |        |   2 |   TABLE ACCESS BY INDEX ROWID| ZKM                |      1 |      3 |      3 |00:00:00.01 |       6 |
|   3 |    BITMAP AND                    |                    |      1 |        |      1 |00:00:00.01 |       4 |       |       |          |        |*  3 |    INDEX RANGE SCAN          | IDX_DO_OWNER       |      1 |    274 |      3 |00:00:00.01 |       3 |
|   4 |     BITMAP CONVERSION FROM ROWIDS|                    |      1 |        |      1 |00:00:00.01 |       2 |       |       |          |        |*  4 |   TABLE ACCESS BY INDEX ROWID| ZKM                |      1 |      9 |      2 |00:00:00.01 |       5 |
|*  5 |      INDEX RANGE SCAN            | IDX_DO_OWNER       |      1 |        |      3 |00:00:00.01 |       2 |       |       |          |        |*  5 |    INDEX RANGE SCAN          | IDX_DO_OBJECT_NAME |      1 |    617 |      3 |00:00:00.01 |       2 |
|   6 |     BITMAP CONVERSION FROM ROWIDS|                    |      1 |        |      1 |00:00:00.01 |       2 |       |       |          |        -------------------------------------------------------------------------------------------------------------
|   7 |      SORT ORDER BY               |                    |      1 |        |      3 |00:00:00.01 |       2 |  2048 |  2048 | 2048  (0)|        
|*  8 |       INDEX RANGE SCAN           | IDX_DO_OBJECT_NAME |      1 |        |      3 |00:00:00.01 |       2 |       |       |          |        Predicate Information (identified by operation id):
--------------------------------------------------------------------------------------------------------------------------------------------        ---------------------------------------------------
                                                                                                                                                    
Predicate Information (identified by operation id):                                                                                                    3 - access("OWNER"='ZKM')
---------------------------------------------------                                                                                                    4 - filter(LNNVL("OWNER"='ZKM'))
                                                                                                                                                       5 - access("OBJECT_NAME" LIKE 'ZKM%')
   5 - access("OWNER"='ZKM')                                                                                                                               filter("OBJECT_NAME" LIKE 'ZKM%')
   8 - access("OBJECT_NAME" LIKE 'ZKM%')
       filter(("OBJECT_NAME" LIKE 'ZKM%' AND "OBJECT_NAME" LIKE 'ZKM%'))

 

 

https://www.cnblogs.com/PiscesCanon/p/18184567

感觉匪夷所思,不应该啊。

也没搜到啥资料。防。

那么对于前边一开始提到的SQL如何优化?

select * from t
where t.col1='1'
and ( instr(t.col2, :1) > 0 or t.col3 = :2 )
order by t.create_time desc;

 

只能拆开使用union了。

如下(hint看情况,不一定cbo能够自动用上):

select a* from (
select /*+ index(t1(col2)) */ t1.* from t1
where t1.col1='1'
and t1.col2 like '%'||:1||'%'
union
select /*+ index(t2(col1)) */ t2.* from t2
where t2.col1='1'
and t2.col3 = :2 
) a
order by a.create_time desc;

 

 

 

随便找一组绑定变量代入,执行了下,原SQL跑0.5s左右,

改造成union的形式,跑0.3s左右。

单次的逻辑读消耗也少了4/5多点。

如果表更大的话,就更明显了,毕竟原SQL是全表扫的。

 

标签:index,00,OBJECT,like,ZKM,Hint,00.01,NAME
From: https://www.cnblogs.com/PiscesCanon/p/18184567

相关文章

  • like to play as kid
    续8篇了,shape上碰壁缓不过劲来,要不换一篇简单点的生息一阵,还是小孩子的游戏放松心情,来扮演一次kid,是pythonforkids,往下刷题,firstgame是bounce,就是弹弹球,加上一个触板就是paddleball,为增加对成人的可玩性,一个球变两个球,速率加快且计分,把代码复制到py文件试试吧补充说一个类......
  • ES索引数据迁移、分片数优化(reindex)
    目录ES索引数据迁移、分片数优化(reindex)业务背景步骤新建索引将原索引数据复制到新索引中校验结果删除原索引给新索引起别名创建新索引的metric脚本整合使用感受ES索引数据迁移、分片数优化(reindex)​ Elasticsearch是⼀个实时的分布式搜索引擎,为⽤户提供搜索服务。当我们创建好......
  • 检索增强生成(RAG)实践:基于LlamaIndex和Qwen1.5搭建智能问答系统
    检索增强生成(RAG)实践:基于LlamaIndex和Qwen1.5搭建智能问答系统什么是RAGLLM会产生误导性的“幻觉”,依赖的信息可能过时,处理特定知识时效率不高,缺乏专业领域的深度洞察,同时在推理能力上也有所欠缺。正是在这样的背景下,检索增强生成技术(Retrieval-AugmentedGeneration,RAG......
  • Unable to execute SonarScanner analysis: Fail to get bootstrap index from server
    1.背景编辑gitlab-ci流水线时,代码分析的job,maven使用sonar报错-mvncleanverifysonar:sonar-Dsonar.login=30c55d3b8d3d2569431fb39f3c488c90643a68442.错误信息[ERROR]Failedtoexecutegoalorg.sonarsource.scanner.maven:sonar-maven-plugin:3.11.0.3922:sonar(def......
  • pd.merge函数合并DataFrame 保留原index
    C=pd.merge(A,B),merge之后C的行数并不会变。但是A的index丢失了,因为merge之后index是重排的。解决办法:方法1:#可以先把A的index保存一下,A、B中含有"col"列A_index=A.indexC=pd.merge(A,B,on="col",how="left")C.index=A_index方法2:#A、B中含有"col"列,set_index设置C......
  • uView Picker 选择器 setIndexs用法
    uView官方文档,质量不高。有很多地方写的不清楚。比如Picker选择器组件。项目中有个页面,属于表单,用了Picker选择器,需要根据数据设置选中项。官方文档如下图。看完根本不知道setIndexs到底要填什么值。应该写个示例。无奈只能看源码。得知应该通过如下方式填写:this.$refs.film......
  • public void add(int index, E element)的方法源码分析
    publicclassArrayList<E>extendsAbstractList<E>implementsList<E>,RandomAccess,Cloneable,java.io.Serializable{publicvoidadd(intindex,Eelement){rangeCheckForAdd(index);//校验数组是否越界......
  • 数据库优化 索引(index)
    介绍索引是帮助数据库高效获取数据的数据结构优缺点:优点:提高数据查询的效率,降低数据的IO成本。通过索引列多数据进行排序,降低数据排序的成本,降低CPU消耗缺点:索引会占存储空间。索引大大提高了查询效率,同时却也降低了insert、update、delete的效率结构MySql数据库支......
  • Fast Training Algorithms for Deep Convolutional Fuzzy Systems With Application t
    类似深度卷积神经网络DCNN,模糊系统领域有个深度卷积模糊系统deepconvolutionalfuzzysystem(DCFS),每一层都是一个模糊系统,上一层的输出是下一层的输入。这篇论文目的是加速DCFS的计算速度,解决可解释性1990年提出,也用反向传播训练DCFS受困于低维度小数据集,大数据量时计算负担太......
  • 在数据库的查询与更新中,CHARINDEX与instr的区别?
    在数据库和字符串处理的领域中,CHARINDEX和INSTR是两个常用的函数,它们都用于查找子字符串在主字符串中的位置。尽管这两个函数在功能上有所重叠,但它们之间存在一些关键的区别,这些区别可能会影响开发者在选择使用哪一个函数时的决策。首先,CHARINDEX是SQLServer中的一个内置函数,它......