Oracle Hint index_combine对于like的局限性

news/发布时间2024/5/21 4:59:20

 

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是全表扫的。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ulsteruni.cn/article/07430021.html

如若内容造成侵权/违法违规/事实不符,请联系编程大学网进行投诉反馈email:xxxxxxxx@qq.com,一经查实,立即删除!

相关文章

docker的一些命令 以及dockerFile语法

文件夹重新命名mv node-v14.18.1-linux-x64 node-v14.18.1 dokcer 命令 将linux的文件复制到docker容器里面 docker cp /usr/local/node-v14.18.1/ 8ec26052dfad:/usr/local/node-v14.18.1 将docker容器里面的文件复制到linux docker container cp ng…

【自动化测试】关键字驱动接口自动化测试

1. 概念:  在软件测试领域,"数据驱动"和"关键字驱动"是两种自动化测试的设计模式, 它们都旨在提高测试效率,减少重复劳动,但它们的实现方式和应用场景有所不同。(1) 数据驱动(Data-Driven Testing, DDT):**优点**     a. 可变数据:测试数据的…

数仓安全:数据脱敏技术深度解析

GaussDB (DWS)产品8.1.1版本发布数据脱敏特性,提供指定用户范围内列级敏感数据的脱敏功能,具有灵活、高效、透明、友好等优点,极大地增强产品的数据安全能力。本文分享自华为云社区《GaussDB(DWS)安全管理之数据脱敏原理与使用方法介绍》,作者: VV一笑。 1. 前言适用版本:…

python教程10-元祖

元组(tuple)与列表类似,不同之处在于元组的元素不能修改。因此很少使用 元组使用小括号 ( ),列表使用方括号 [ ] 元组中只包含一个元素时,需要在元素后面添加逗号 , ,否则括号会被当作运算符使用:元祖调用:修改元祖 元组中的元素值是不允许修改的,但我们可以对元组进行连…

Selenium4自动化测试4--元素定位By.XPATH,元素定位最佳顺序

7-通过xpath定位,By.XPATHxpath是什么?XPath 是一门在 XML 文档中查找信息的语言xml是什么?XML(可扩展标记语言),主要用于传输数据为什么可以使用xpath定位html? XPath(XML路径语言)是一种用于在XML文档中定位元素的语言,它可以用于定位HTML文档中的元素。尽管XML和H…

前端技术选型时有用的网站

npm-compare.com比如我们想比较 react-query和 swr,可以访问 https://npm-compare.com/react-query,swr 查看结果,页面提供了下载量,star 数量,lisense 等的对比,方便我们做出决策。bundlephobia.com比较完了这些,我们可能还想知道哪个包的体积更小,更轻量,这时可以使用…