zoukankan      html  css  js  c++  java
  • SELECT MIN(ID),MAX(ID) FROM TABLE 优化问题

     2011/07/20到支付宝面试,被问及一个问题 SELECT MIN(ID),MAX(ID) FROM TABLE 如何优化

    好的现在来做个实验:

    SQL>  select * from v$version where rownum<2;
    
    BANNER
    --------------------------------------------------------------------------------
    Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
    
    SQL>  create table test as select * from dba_objects;
    
    Table created.
    
    SQL>  alter table test modify object_id not null;
    
    Table altered.
    
     
    SQL> create index i_object_id on test(object_id);
    
    Index created.
     
    SQL> select max(object_id),min(object_id) from test;
    
    MAX(OBJECT_ID) MIN(OBJECT_ID)
    -------------- --------------
             74644              2
    
    Elapsed: 00:00:00.34
    
    Execution Plan
    ----------------------------------------------------------
    Plan hash value: 1751978921
    
    -------------------------------------------------------------------------------------
    | Id  | Operation             | Name        | Rows  | Bytes | Cost (%CPU)| Time     |
    -------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT      |             |     1 |     5 |    37   (0)| 00:00:01 |
    |   1 |  SORT AGGREGATE       |             |     1 |     5 |            |          |
    |   2 |   INDEX FAST FULL SCAN| I_OBJECT_ID | 72860 |   355K|    37   (0)| 00:00:01 |
    -------------------------------------------------------------------------------------
    
    
    Statistics
    ----------------------------------------------------------
              1  recursive calls
              0  db block gets
            167  consistent gets
            145  physical reads
              0  redo size
            501  bytes sent via SQL*Net to client
            420  bytes received via SQL*Net from client
              2  SQL*Net roundtrips to/from client
              0  sorts (memory)
              0  sorts (disk)
              1  rows processed
    
    可以看到CBO选择了 INDEX FAST FULL SCAN,有145个物理读,167个逻辑读,现在改写SQL如下
     
    SQL> select (select min(object_id) min_id from test a),(select max(object_id) max_id from test b) from dual;
    
    (SELECTMIN(OBJECT_ID)MIN_IDFROMTESTA) (SELECTMAX(OBJECT_ID)MAX_IDFROMTESTB)
    ------------------------------------- -------------------------------------
                                        2                                 74644
                                        
    Execution Plan
    ----------------------------------------------------------
    Plan hash value: 4224666897
    
    ------------------------------------------------------------------------------------------
    | Id  | Operation                  | Name        | Rows  | Bytes | Cost (%CPU)| Time     |
    ------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT           |             |     1 |       |     2   (0)| 00:00:01 |
    |   1 |  SORT AGGREGATE            |             |     1 |     5 |            |          |
    |   2 |   INDEX FULL SCAN (MIN/MAX)| I_OBJECT_ID |     1 |     5 |     2   (0)| 00:00:01 |
    |   3 |  SORT AGGREGATE            |             |     1 |     5 |            |          |
    |   4 |   INDEX FULL SCAN (MIN/MAX)| I_OBJECT_ID |     1 |     5 |     2   (0)| 00:00:01 |
    |   5 |  FAST DUAL                 |             |     1 |       |     2   (0)| 00:00:01 |
    ------------------------------------------------------------------------------------------
    
    
    Statistics
    ----------------------------------------------------------
              1  recursive calls
              0  db block gets
              4  consistent gets
              0  physical reads
              0  redo size
            547  bytes sent via SQL*Net to client
            420  bytes received via SQL*Net from client
              2  SQL*Net roundtrips to/from client
              0  sorts (memory)
              0  sorts (disk)
              1  rows processed
     
    可以看到逻辑读降低为4,大家看看这个是不是最优化的方法?还有更进一步的方法优化吗?支付宝说这个案例很经典,可能是我水平太低了,只能想出这个方法
    
     
    ----update,我能想到的另外一种方法,不过逻辑读也是4---------------------
     
    SQL> select (select /*+ index_asc(test i_object_id) */ object_id from test where rownum=1) min
    ,(select /*+ index_desc(test i_object_id) */ object_id from test where rownum=1) max from dual;  2
    
           MIN        MAX
    ---------- ----------
             2      74644
    
    
    Execution Plan
    ----------------------------------------------------------
    Plan hash value: 91314419
    
    -------------------------------------------------------------------------------------------
    | Id  | Operation                   | Name        | Rows  | Bytes | Cost (%CPU)| Time     |
    -------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT            |             |     1 |       |     2   (0)| 00:00:01 |
    |*  1 |  COUNT STOPKEY              |             |       |       |            |          |
    |   2 |   INDEX FULL SCAN           | I_OBJECT_ID |     1 |     5 |     2   (0)| 00:00:01 |
    |*  3 |  COUNT STOPKEY              |             |       |       |            |          |
    |   4 |   INDEX FULL SCAN DESCENDING| I_OBJECT_ID |     1 |     5 |     2   (0)| 00:00:01 |
    |   5 |  FAST DUAL                  |             |     1 |       |     2   (0)| 00:00:01 |
    -------------------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       1 - filter(ROWNUM=1)
       3 - filter(ROWNUM=1)
    
    
    Statistics
    ----------------------------------------------------------
              1  recursive calls
              0  db block gets
              4  consistent gets
              0  physical reads
              0  redo size
            479  bytes sent via SQL*Net to client
            420  bytes received via SQL*Net from client
              2  SQL*Net roundtrips to/from client
              0  sorts (memory)
              0  sorts (disk)
              1  rows processed
    

  • 相关阅读:
    iterm2 关闭命令行的行数限制
    设置Mac关闭显示器后不睡眠
    设置iPhone内容隔空投送到mac
    Mac关闭动画效果
    mac使用Jmeter
    Mac 设置文件夹共享
    设置iPhone可以投屏到mac上
    Mac关闭显示亮度自动调节功能
    Mac系统无法使用root用户
    Mac设置主显示器
  • 原文地址:https://www.cnblogs.com/hehe520/p/6330573.html
Copyright © 2011-2022 走看看