【发布时间】:2020-03-07 22:15:12
【问题描述】:
我正在使用 Oracle 数据库 《Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 64bit》
我正面临一种我不知道是对还是错的行为。
例如下面的查询
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
我在下面创建了一个索引:
CREATE INDEX IDX_HHH_S_V_T_DATE ON HHH (S, v_date desc, t_date desc) compute statistics
优化器总是选择这个索引,但是当我提到“并行”提示时:
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
当试图通过“INDEX”提示强制优化器使用索引时:
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
【问题讨论】:
-
您应该发布两个查询的execution plans。基本上,您似乎在串行执行中进行了较大的 索引范围扫描 并切换到并行 Oracle 认为
full scan会更好。您可以在并行模式下提示索引访问并比较成本来验证它。 -
看起来 Oracle 优化器估计在并行情况下使用索引是一种开销。驱动表是否分区?还有并行提示的查询性能不好,为什么要它使用索引?尝试用索引名称给出提示,看看是否会颠覆计划。
-
谢谢Marmite,我会编辑帖子并放上2个执行计划。
-
感谢 Sanchit,不,此表未分区。
-
第一条评论中提供的链接向您展示了如何以文本形式发布执行计划
标签: oracle oracle11g sql-tuning