当查询语句的 WHERE 子句中包含组合的 OR 条件时,无法直接使用单一索引进行查询,OceanBase 数据库会基于代价考虑是否将 OR 条件改写为 UNION 语句。由于缺失统计信息等原因,OceanBase 数据库优化器可能无法准确估算改写前后的代价,这个时候就需要使用 USE_CONCAT Hint 来强制将 OR 改写为 UNION。
详细信息
OceanBase 数据库中 USE_CONCAT Hint 指示优化器使用 UNION ALL 运算符将查询 WHERE 子句中的组合 OR 条件转换为复合查询。如果没有设置 USE_CONCAT Hint,则仅当使用串联查询的成本低于不使用的成本时,才会发生此转换。本文介绍使用 use_concat hint 优化 or 语句的性能。
USE_CONCAT Hint 的语法如下。
/*+ USE_CONCAT [ ( @queryblock ) ] */
USE_CONCAT Hint 的使用示例
原始 SQL。
select * from TEST_TB where ( acctid <> 0 and acctid = to_number(?) ) or ( SUBSID <> 0 AND SUBSID = to_number(?) );执行计划如下:
|================================================= |ID|OPERATOR |NAME |EST. ROWS |COST | -------------------------------------------------- |0 |TABLE SCAN|TEST_TB |13 |23460004 | ==================================================执行耗时Empty set (7.301 sec) 。
使用 USE_CONCAT Hint 指示优化器。
select/*+ USE_CONCAT */ * from TEST_TB where ( acctid <> 0 and acctid = to_number(?) ) or ( SUBSID <> 0 AND SUBSID = to_number(?) );执行计划如下:
|================================================== |ID|OPERATOR |NAME |EST. ROWS |COST | --------------------------------------------------- |0 |UNION ALL | |2 |92 | |1 | TABLE SCAN|TEST_TB(IX1) |1 |46 | |2 | TABLE SCAN|TEST_TB(IX2) |1 |46 | ===================================================执行耗时 Empty set (0.094 sec) 。
适用版本
OceanBase 数据库所有版本。