like后面跟select表达式特别慢

1、OCEANBASE V4.2.1.6版本

执行查询逻辑的时候 特别慢貌似没有走索引 , sql和执行计划如下 , 同样的sql在oracle上面执行会走索引 , 试了hint优化 /*+ index() */方法不生效 反而更慢了 , 但是把like后面的结果单独查出来在替换select表达式就很快

sql:
SELECT T.CODE
FROM T_DIM_OBJECT T
WHERE T.PATH LIKE (( SELECT A.PATH FROM T_DIM_OBJECT A WHERE A.OBJECT_ID=(‘11ec9ba9f514ebe6b4370b375bfd4359’) )||’%’)
AND T.STATUS = ‘ENABLE’

你这个应该是ob-oracle模式吧?麻烦发一下ob详细版本

OB的执行计划是什么,发下看下

你好,你提的这个技术问题牵涉到OceanBase企业版范围内的功能细节;针对此类问题,建议你通过以下方式寻求帮助:

  1. 如你所在的企业客户已签署OceanBase企业版销售合同,请你联系客户经理;
  2. 如你所在的企业客户尚未签署OceanBase企业版销售合同,你可通过OceanBase官网商务咨询页面留下你的联系方式,OceanBase企业版的业务顾问会在一个工作日内与你联系。

另外,我们欢迎你使用社区版,并在论坛/社群中分享你对社区版本的想法、经验和问题,与其他社区成员共同交流。

@论坛小助手

根据文档库中的信息,针对您提到的 LIKE 后跟 SELECT 表达式执行特别慢的问题,可以尝试以下几种方法来优化查询性能。您的问题合理,并且可以通过一些已知的技术手段进行解决。

1. 避免在 LIKE 中使用子查询

从您提供的 SQL 和执行计划来看,LIKE 操作符后面跟着一个子查询,这会导致 OceanBase 数据库无法有效地利用索引。通常情况下,数据库引擎对于 LIKE 后面带有复杂表达式的查询难以生成最优的执行计划。因此,建议将子查询的结果提前计算出来,再用于主查询中。正如您所提到的,当把 LIKE 后面的结果单独查出来替换 SELECT 表达式时速度会快很多,这是因为此时可以直接使用索引。

优化后的SQL:

-- 先获取子查询结果
SET @path = (SELECT A.PATH FROM T_DIM_OBJECT A WHERE A.OBJECT_ID = '11ec9ba9f514ebe6b4370b375bfd4359');

-- 使用变量代替子查询
SELECT T.CODE 
FROM T_DIM_OBJECT T 
WHERE T.PATH LIKE CONCAT(@path, '%') 
AND T.STATUS = 'ENABLE';

2. 确保索引的有效性

确保 T_DIM_OBJECT 表上的 PATH 列上有适当的索引。如果 PATH 列上没有索引或者索引不合适,即使不使用子查询也可能导致全表扫描。请检查并创建必要的索引:

CREATE INDEX idx_path ON T_DIM_OBJECT(PATH);

同时,请注意,如果 PATH 列经常被更新,那么过多的索引可能会降低写入性能。参考文档《关于索引》中的“使用原则”。

3. 考虑使用 Hint 强制走索引

虽然您提到使用 /*+ index() */ 提示后反而更慢了,但这可能是因为提示的方式不对或不适合当前场景。您可以尝试不同的提示方式,例如指定具体的索引名称:

SELECT /*+ INDEX(T idx_path) */ T.CODE 
FROM T_DIM_OBJECT T 
WHERE T.PATH LIKE (( SELECT A.PATH FROM T_DIM_OBJECT A WHERE A.OBJECT_ID='11ec9ba9f514ebe6b4370b375bfd4359' ) || '%')
AND T.STATUS = 'ENABLE';

4. 收集统计信息

有时,由于缺乏准确的统计信息,优化器可能无法选择最佳的执行计划。可以通过手动收集统计信息来帮助优化器做出更好的决策:

ANALYZE TABLE T_DIM_OBJECT;

5. 检查执行计划

最后,再次确认优化后的查询是否确实走了索引。通过 EXPLAIN EXTENDED 查看详细的执行计划,确保没有出现不必要的全表扫描或其他低效操作。

EXPLAIN EXTENDED SELECT T.CODE 
FROM T_DIM_OBJECT T 
WHERE T.PATH LIKE (( SELECT A.PATH FROM T_DIM_OBJECT A WHERE A.OBJECT_ID='11ec9ba9f514ebe6b4370b375bfd4359' ) || '%')
AND T.STATUS = 'ENABLE';

以上建议基于现有文档和常见实践,希望能对您有所帮助。如果您还有其他疑问或需要进一步的帮助,请随时告知。

具体信息可参考以下文档:

  1. 关于索引
  2. trace_log_slow_query_watermark
  3. SQL 性能问题的典型场景和排查思路
  4. SQL 调优典型场景和案例
  5. OceanBase 集群运维管理之用户实操
  6. 表扫描方式规范
  7. 计划缓存概述
  8. 常见的 SQL 调优方式
  9. 阅读和管理 OceanBase 数据库 SQL 执行计划

执行计划是什么,发出来看看

学习一下解决方案