Oracle 聚合函数大幅减慢查询速度

use*_*653 5 performance oracle aggregate

我有一个包含 ~12M 行数据的表。这是表结构:

SYSTEM_ID
BATCH_ID
MEASUREMENT_INDEX,
PARAMETER_ONE,
PARAMETER_TWO
Run Code Online (Sandbox Code Playgroud)

主键由前三列组成。我也有一个关于SYSTEM_ID ASC,的索引BATCH_ID ASC

如果我执行以下查询:

SELECT PARAMETER_ONE 
  FROM RESULTS_TABLE 
 WHERE SYSTEM_ID=1 
   AND BATCH_ID=100;
Run Code Online (Sandbox Code Playgroud)

结果在大约 0.002 秒后返回。

但是,当我尝试执行任何聚合函数时,例如SUM, MAX, AVG, STDDEV,查询时间会增加到 400 秒左右!我已经尝试了这个查询的各种排列,例如:

SELECT AVG(PARAMETER_ONE) 
  FROM ( SELECT PARAMETER_ONE 
           FROM RESULTS_TABLE 
          WHERE SYSTEM_ID=1 
            AND BATCH_ID=100
        );
Run Code Online (Sandbox Code Playgroud)

和:

SELECT DISTINCT
       AVG(PARAMETER_ONE) over (partition by system_id, batch_id)
 FROM RESULTS_TABLE
WHERE SYSTEM_ID = 123
  AND BATCH_ID = 10;
Run Code Online (Sandbox Code Playgroud)

这些似乎都没有区别。有没有其他人有这个问题??

============================

更多细节

聚合函数查询的解释计划是:

Plan hash value: 2759933517

-------------------------------------------------------------------------------------------------------------
| Id  | Operation                    | Name                         | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |                              |     1 |    32 |     2   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE              |                              |     1 |    32 |            |          |
|   2 |   TABLE ACCESS BY INDEX ROWID| RESULTS_DATA                 |     1 |    32 |     2   (0)| 00:00:01 |
|*  3 |    INDEX RANGE SCAN          | RESULTS_DATA_INDEX1          |     1 |       |     1   (0)| 00:00:01 |
Run Code Online (Sandbox Code Playgroud)

谓词信息(由操作 id 标识):

3 - 访问(“SYSTEM_ID”='123' AND “BATCH_ID”='10')

只是一个简单选择的解释计划是:

Plan hash value: 1958859493

------------------------------------------------------------------------------------------------------------
| Id  | Operation                   | Name                         | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |                              |     1 |    32 |     2   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| RESULTS_DATA                 |     1 |    32 |     2   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | RESULTS_DATA_INDEX1          |     1 |       |     1   (0)| 00:00:01 |
------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("SYSTEM_ID"='123' AND "BATCH_ID"='10')
Run Code Online (Sandbox Code Playgroud)

令人惊讶的是,两者的解释计划似乎都声称执行该查询只需要 1 秒,但它绝对不是,无论是在 SQL Developer 还是 SQL Plus 中......

==================================================

更新

这是按要求使用聚合函数的查询的自动跟踪:

SQL> set autotrace traceonly explain statistics
SQL> SELECT avg(tail_intensity) FROM RESULTS_DATA WHERE SYSTEM_ID = '12
3' AND BATCH_ID = '10';


Execution Plan
----------------------------------------------------------
Plan hash value: 2759933517

--------------------------------------------------------------------------------

-----------------------------

| Id  | Operation                    | Name                         | Rows  | Bytes | Cost (%CPU)| Time     |

-------------------------------------------------------------------------------------------------------------

|   0 | SELECT STATEMENT             |                              |     1 | 32    |     2   (0)| 00:00:01 |

|   1 |  SORT AGGREGATE              |                              |     1 | 32    |            |          |

|   2 |   TABLE ACCESS BY INDEX ROWID| RESULTS_DATA                 |     1 | 32    |     2   (0)| 00:00:01 |

|*  3 |    INDEX RANGE SCAN          | RESULTS_DATA_INDEX1          |     1 |       |     1   (0)| 00:00:01 |

-------------------------------------------------------------------------------------------------------------


Predicate Information (identified by operation id):
---------------------------------------------------

   3 - access("SYSTEM_ID"='123' AND "BATCH_ID"='10')


Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
     437569  consistent gets
     437129  physical reads
          0  redo size
        433  bytes sent via SQL*Net to client
        416  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed
Run Code Online (Sandbox Code Playgroud)

use*_*653 5

感谢您的所有意见 - 我似乎已经解决了。我使用以下方法重新计算了表统计信息:

SQL> EXEC DBMS_STATS.GATHER_TABLE_STATS(OWNNAME=>USER,TABNAME=>'RESULTS
_DATA');
Run Code Online (Sandbox Code Playgroud)

在此之后,查询工作正常。