我有一个甲骨文解释计划如下:
Plan hash value: 2484140766
--------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 180K| 84M| 5 (0)| 00:00:01 |
|* 1 | COUNT STOPKEY | | | | | |
| 2 | VIEW | | 180K| 84M| 5 (0)| 00:00:01 |
|* 3 | TABLE ACCESS BY INDEX ROWID | OSTRICH | 6500K| 793M| 5 (0)| 00:00:01 |
|* 4 | INDEX RANGE SCAN DESCENDING| OSTRICH_ENDDATE_IDX_2 | 1 | | 4 (0)| 00:00:01 |
--------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(ROWNUM<=180000)
3 - filter("OSTRICH_STATUS_ID"=2)
4 - access(SYS_OP_DESCEND("END_DATE")>=SYS_OP_DESCEND(SYSDATE@!))
filter(SYS_OP_UNDESCEND(SYS_OP_DESCEND("END_DATE"))<=SYSDATE@!)
我一直在试图理解下面这两行是怎么回事:
4 - access(SYS_OP_DESCEND("END_DATE")>=SYS_OP_DESCEND(SYSDATE@!))
filter(SYS_OP_UNDESCEND(SYS_OP_DESCEND("END_DATE"))<=SYSDATE@!)
你要做什么 SYS_OP_UNDESCEND
以及 SYS_OP_DESCEND
什么意思?
解释计划引用的索引(我认为)称为降序索引(我对oracle索引了解不多。)该索引的ddl是:
CREATE INDEX
OSTRICH_ENDDATE_IDX_2
ON
OSTRICH
(
"END_DATE" DESC
);
实际查询如下所示:
SELECT
l.id,
l.end_date,
l.status
FROM
(
SELECT
*
from OSTRICH l2
where END_DATE <= SYSDATE
and OSTRICH_STATUS_ID = 2
order by l2.END_DATE
) l
WHERE ROWNUM <= 180000;
你要做什么 SYS_OP_UNDESCEND
以及 SYS_OP_DESCEND
什么意思?这个查询花费的时间比我预期的要长得多,我正在试图理解降序和降序对查询有什么影响?
2条答案
按热度按时间tktrz96b1#
oracle实现了降序索引,就好像它是一个基于函数的索引。当查询使用函数调用时调用基于函数的索引;因此联邦调查局
upper(col1)
将在where子句筛选时使用upper(col1) = 'WHATEVER'
.在本例中,我认为sys\u op\u descent是oracle在创建降序索引时使用的“函数”,我认为它调用sys\u op\u undescend是因为where子句不适合降序索引。这并不奇怪的表现糟透了。
很少有使用降序索引的用例是个好主意。你为什么在这张table的这一栏上用这个?
假设使用索引有很好的理由,并且您不能直接删除它,那么提高性能的最佳选择就是不将索引用于此查询。这样做可以防止优化器不使用索引:
uqxowvwt2#
SYS_OP_UNDESCEND
以及SYS_OP_DESCEND
当使用基于函数的索引或指定了索引子句中的排序操作时,cbo使用的内部函数出现在解释计划中。在您的例子中,您使用的是带有sort子句的索引
您的计划显示了以下两种操作:
access(SYS_OP_DESCEND("END_DATE")>=SYS_OP_DESCEND(SYSDATE@!))
filter(SYS_OP_UNDESCEND(SYS_OP_DESCEND("END_DATE"))<=SYSDATE@!)
第一个操作是access,基于索引本身的desc index子句,第二个操作是filter。两者都出现是因为查询是针对索引的性质进行的。我永远不会在任何索引中使用这个子句,除非访问总是以这种方式进行,这是非常罕见的,因为sql通常使用不同的方式进行排序。
还有一个错误:(在20.1中修复)
错误27589260基于函数的索引中虚拟列替换导致排序顺序错误
当表中存在虚拟列并且使用了基于函数的索引时,这会降低查询的性能。