Oracle在使用并行提示时跳过索引

Oracle在使用并行提示时跳过索引,oracle,oracle11g,sql-tuning,Oracle,Oracle11g,Sql Tuning,我正在使用Oracle数据库 Oracle数据库12c企业版12.1.0.2.0版本64位 我正面临一种行为,我不知道这是对的还是有什么不对 例如下面的查询 SELECT * FROM (SELECT x, y, z, ROW_NUMBER() OVER (PARTITION BY x ORDER BY last_date DESC) ROW1 FROM HHH WHERE s = 0 AND v_Date <= TO_DATE(

我正在使用Oracle数据库 Oracle数据库12c企业版12.1.0.2.0版本64位

我正面临一种行为,我不知道这是对的还是有什么不对

例如下面的查询

SELECT *
FROM   (SELECT x, y, z, ROW_NUMBER() OVER (PARTITION BY x ORDER BY last_date DESC) ROW1 
         FROM HHH
         WHERE s = 0
         AND v_Date <= TO_DATE('20191110','YYYYMMDD') 
         AND t_Date >= TO_DATE('20191110','YYYYMMDD')
WHERE   ROW1 = 1
优化器总是选择这个索引,但当我提到并行提示时:

 SELECT *
    FROM   (SELECT /*+ PARALLEL(8) */ x, y, z, ROW_NUMBER() OVER (PARTITION BY x ORDER BY last_date DESC) ROW1 
             FROM HHH
             WHERE s = 0
             AND v_Date <= TO_DATE('20191110','YYYYMMDD') 
             AND t_Date >= TO_DATE('20191110','YYYYMMDD')
    WHERE   ROW1 = 1
优化器选择跳过此索引

我尝试过的解决方案仍然是一样的:

我把桌子改成平行的8号 我把索引改为平行8 尝试强制优化器使用索引提示使用索引时:

 SELECT *
    FROM   (SELECT /*+ PARALLEL(8) INDEX(HHH (IDX_HHH_S_V_T_DATE))*/ x, y, z, ROW_NUMBER() OVER (PARTITION BY x ORDER BY last_date DESC) ROW1 
             FROM HHH
             WHERE s = 0
             AND v_Date <= TO_DATE('20191110','YYYYMMDD') 
             AND t_Date >= TO_DATE('20191110','YYYYMMDD')
    WHERE   ROW1 = 1

这种行为没有错。你强迫神谕使用8的DOP。假设DOP为8,它考虑了2条访问路径——并行索引范围|全|快速全扫描和并行全表扫描。不管是对是错,它都认为全表扫描成本更低


请注意,在上一个示例中,您并没有真正强制执行索引扫描。您的提示没有正确指定。正确的提示应该是indexhh IDX_HHH_S_V_T_DATE no嵌套括号。

您应该发布两个查询的结果。基本上,您似乎在串行执行中进行了大范围的索引扫描,并且切换到并行Oracle认为完全扫描会更好。您可以在并行模式下提示索引访问,并比较成本来验证它。看起来Oracle optimizer在并行模式下使用索引是一种开销。驾驶台是分区的吗?还有,带并行提示的查询执行得不好,为什么要使用索引?试着用索引名给出一个提示,看看这是否会改变计划。谢谢Marmite,我将编辑帖子并放入2执行计划。谢谢Sanchit,不,这个表没有分区。第一条评论中提供的链接显示了如何将执行计划作为文本发布
 SELECT *
    FROM   (SELECT /*+ PARALLEL(8) INDEX(HHH (IDX_HHH_S_V_T_DATE))*/ x, y, z, ROW_NUMBER() OVER (PARTITION BY x ORDER BY last_date DESC) ROW1 
             FROM HHH
             WHERE s = 0
             AND v_Date <= TO_DATE('20191110','YYYYMMDD') 
             AND t_Date >= TO_DATE('20191110','YYYYMMDD')
    WHERE   ROW1 = 1