在oracle的解释计划中,sys\u op\u undescend和sys\u op\u descent是什么?

5anewei6  于 2021-07-24  发布在  Java
关注(0)|答案(2)|浏览(585)

我有一个甲骨文解释计划如下:

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 什么意思?这个查询花费的时间比我预期的要长得多,我正在试图理解降序和降序对查询有什么影响?

tktrz96b

tktrz96b1#

oracle实现了降序索引,就好像它是一个基于函数的索引。当查询使用函数调用时调用基于函数的索引;因此联邦调查局 upper(col1) 将在where子句筛选时使用 upper(col1) = 'WHATEVER' .
在本例中,我认为sys\u op\u descent是oracle在创建降序索引时使用的“函数”,我认为它调用sys\u op\u undescend是因为where子句不适合降序索引。这并不奇怪的表现糟透了。
很少有使用降序索引的用例是个好主意。你为什么在这张table的这一栏上用这个?
假设使用索引有很好的理由,并且您不能直接删除它,那么提高性能的最佳选择就是不将索引用于此查询。这样做可以防止优化器不使用索引:

SELECT
 l.id,
 l.end_date,
 l.status
FROM
    (
        SELECT /*+ NO_INDEX(l2 OSTRICH_ENDDATE_IDX_2) */ 
            *
        from OSTRICH l2
        where END_DATE <= SYSDATE
            and OSTRICH_STATUS_ID = 2
        order by l2.END_DATE
    ) l
WHERE ROWNUM <= 180000;
uqxowvwt

uqxowvwt2#

SYS_OP_UNDESCEND 以及 SYS_OP_DESCEND 当使用基于函数的索引或指定了索引子句中的排序操作时,cbo使用的内部函数出现在解释计划中。
在您的例子中,您使用的是带有sort子句的索引

CREATE INDEX
    OSTRICH_ENDDATE_IDX_2
ON
    OSTRICH
    (
        "END_DATE" DESC
    );

您的计划显示了以下两种操作:
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基于函数的索引中虚拟列替换导致排序顺序错误
当表中存在虚拟列并且使用了基于函数的索引时,这会降低查询的性能。

相关问题