3

我有一条存在性能问题的 SQL 语句。

添加以下索引和使用该索引的 SQL 提示可将性能提高 10 倍,但我不明白为什么。BUS_ID 是主键的一部分(T1.REF 是键的另一部分)和 T1 表上的聚集索引。

T1 表有大约 100,000 行。BUS_ID 只有 6 个不同的值。同样,T1.STATUS 列只能有有限数量的可能性,其中大多数(99%)将是相同的值。

如果我在没有提示的情况下运行查询(/*+ INDEX (T1 T1_IDX1) NO_UNNEST */),则需要 5 秒,而有提示则需要 0.5 秒。我不明白索引如何帮助子查询,因为子查询中的任何“where”或“join”子句中都没有使用 T1.STATUS。

我错过了什么?

SELECT 
          /*+ NO_UNNEST */ 
          t1.bus_id, 
          t1.ref, 
          t2.cust, 
          t3.cust_name, 
          t2.po_number, 
          t1.status_old, 
          t1.status, 
          t1.an_status 
FROM      t1 
LEFT JOIN t2 
ON        t1.bus_id = t2.bus_id 
AND       t1.ref = t2.ref 
JOIN      t3 
ON        t3.cust = t2.cust 
AND       t3.bus_id  = t2.bus_id 
WHERE     ( 
                    status IN ('A', 'B', 'C') AND status_old IN ('X', 'Y')) 
            AND EXISTS 
          ( SELECT /*+ INDEX ( T1 T1_IDX1) NO_UNNEST */ 
                 * 
                 FROM   t1 
                 WHERE  ( EXISTS ( SELECT  /*+ NO_UNNEST */ 
                                      * 
                                      FROM   t6 
                                      WHERE  seq IN ( '0', '2' ) 
                                      AND    t1.bus_id = t6.bus_id) 
                                      OR (EXISTS
                                      (SELECT /*+ NO_UNNEST */ 
                                                    * 
                                             FROM   t6 
                                             WHERE  seq = '1' 
                                             AND    (an_status = 'Y' 
                                                    OR     
                                                    an_status = 'X') 
                                             AND    t1.bus_id = t6.bus_id)) 
                        AND t2.ref = t1.ref)) 
                        AND USER IN ('FRED') 
                        AND ( t2.status != '45' 
                            AND t2.status != '20') 
                        AND NOT EXISTS ( SELECT 
                        /*+ NO_UNNEST */ 
                        * 
                         FROM   t4 
                         WHERE  EXISTS 
                                ( 
                                       SELECT 
                                              /*+ NO_UNNEST */ 
                                              * 
                                       FROM   t5 
                                       WHERE  pd IN ( '1', 
                                                            '0' ) 
                                       AND    appl = 'RYP' 
                                       AND    appl_id IN ( 'RL100') 
                                       AND    t4.id = t5.id) 
                         AND    t2.ref = p.ref 
                         AND    t2.bus_id = p.bus_id);

编辑包括解释计划和索引。

Without Index hint

------------------------------------------------------|-------------------------------------
            Operation            |      Options       |Cost| # |Bytes | CPU Cost | IO COST 
------------------------------------------------------|-------------------------------------
select statement                 |                    | 20 | 1 | 211  | 15534188 |    19   |
 view                            |                    | 20 | 1 | 211  | 15534188 |    19   |
   count                         |                    |    |   |      |          |         |
     view                        |                    | 20 | 1 | 198  | 15534188 |    19   |
      sort                       |  ORDER BY          | 20 | 1 | 114  | 15534188 |    19   |
        nested loops             |                    | 7  | 1 | 114  |    62487 |     7   |
         nested loops            |                    | 7  | 1 | 114  |    62487 |     7   |
          nested loops           |                    | 6  | 1 |  84  |    53256 |     6   |
           inlist iterator       |                    |    |   |      |          |         |
            TABLE access t1      |  INDEX ROWID       | 4  | 1 |  29  |    36502 |     4   |
             index-t1_idx#3      |  RANGE SCAN        | 3  | 1 |      |    28686 |     3   |
           TABLE access - t2     |  INDEX ROWID       | 2  | 1 |  55  |    16754 |     2   |
            index t2_idx#0       |  UNIQUE SCAN       | 1  | 1 |      |     9042 |     1   |
             filter              |                    |    |   |      |          |         |
              TABLE access-t1    |  INDEX ROWID       | 2  | 1 |  15  |     7433 |     2   |
              TABLE access-t6    |  INDEX ROWID       | 3  | 1 |   4  |    23169 |     3   |
               index-t6_idx#0    |  UNIQUE RANGE SCAN | 1  | 3 |      |     7721 |     1   |
              filter             |                    |    |   |      |          |         |
               TABLE access-t6   |  INDEX ROWID       | 2  | 2 |   8  |    15363 |     2   |
                index-t6_idx#0   |  UNIQUE RANGE SCAN | 1  | 3 |      |     7521 |     1   |
             index-t4_idx#1      |  RANGE SCAN        | 3  | 1 |  28  |    21584 |     3   |
              inlist iterator    |                    |    |   |      |          |         |
               index-t5_idx#1    |  RANGE SCAN        | 4  | 1 |  24  |    42929 |     4   |
          index-t3_idx#0         |  INDEX UNIQUE SCAN | 0  | 1 |      |     1900 |     0   |
         TABLE access-t3         |  INDEX ROWID       | 1  | 1 |  30  |     9231 |     1   |
--------------------------------------------------------------------------------------------

带索引提示

------------------------------------------------------|-------------------------------------
            Operation            |      Options       |Cost| # |Bytes | CPU Cost | IO COST 
------------------------------------------------------|-------------------------------------
select statement                 |                    | 21 | 1 | 211  | 15549142 |    19   |
 view                            |                    | 21 | 1 | 211  | 15549142 |    19   |
   count                         |                    |    |   |      |          |         |
     view                        |                    | 21 | 1 | 198  | 15549142 |    19   |
      sort                       |  ORDER BY          | 21 | 1 | 114  | 15549142 |    19   |
        nested loops             |                    | 7  | 1 | 114  |    62487 |     7   |
         nested loops            |                    | 7  | 1 | 114  |    62487 |     7   |
          nested loops           |                    | 6  | 1 |  84  |    53256 |     6   |
           inlist iterator       |                    |    |   |      |          |         |
            TABLE access t1      |  INDEX ROWID       | 4  | 1 |  29  |    36502 |     4   |
             index-t1_idx#3      |  RANGE SCAN        | 3  | 1 |      |    28686 |     3   |
           TABLE access - t2     |  INDEX ROWID       | 2  | 1 |  55  |    16754 |     2   |
            index t2_idx#0       |  UNIQUE SCAN       | 1  | 1 |      |     9042 |     1   |
             filter              |                    |    |   |      |          |         |
              TABLE access-t1    |  INDEX ROWID       | 3  | 1 |  15  |    22387 |     2   |
               index-t1_idx#1    |  FULL SCAN         | 2  |97k|      |    14643 |         |
              TABLE access-t6    |  INDEX ROWID       | 3  | 1 |   4  |    23169 |     3   |
               index-t6_idx#0    |  UNIQUE RANGE SCAN | 1  | 3 |      |     7721 |     1   |
              filter             |                    |    |   |      |          |         |
               TABLE access-t6   |  INDEX ROWID       | 2  | 2 |   8  |    15363 |     2   |
                index-t6_idx#0   |  UNIQUE RANGE SCAN | 1  | 3 |      |     7521 |     1   |
             index-t4_idx#1      |   RANGE SCAN       | 3  | 1 |  28  |    21584 |     3   |
              inlist iterator    |                    |    |   |      |          |         |
               index-t5_idx#1    |  RANGE SCAN        | 4  | 1 |  24  |    42929 |     4   |
          index-t3_idx#0         |  INDEX UNIQUE SCAN | 0  | 1 |      |     1900 |     0   |
         TABLE access-t3         |  INDEX ROWID       | 1  | 1 |  30  |     9231 |     1   |
--------------------------------------------------------------------------------------------

表索引

CREATE INDEX T1_IDX#1 ON T1 (BUS_ID, STATUS)
4

0 回答 0