问题描述
我有一个表t包含三个字段accountno,tran_date,金额和金额始终> 0。
。
There are many records for each accountno。 I want to select all the accountnos where the sum(amount) > 100。
简单的查询是这样的
This query is taking time , as there are many records for each account。 I want to optimise this query , in such a way
一旦某些记录的总和> 100,就不应进一步处理该帐户,是否可能?
。
There are many records for each accountno。 I want to select all the accountnos where the sum(amount) > 100。
简单的查询是这样的
select accountno from t group by accountno having sum(amount) > 100;
This query is taking time , as there are many records for each account。 I want to optimise this query , in such a way
一旦某些记录的总和> 100,就不应进一步处理该帐户,是否可能?
专家解答
带有whaving子句的group by是编写此查询的最佳方法。
但是有一个技巧可用:
物化视图!
这些存储查询的结果。如果每个帐户在表中有 “许多” 行,这可以大大减少您处理的行数。而且,其他一切都相等,更少的行 => 更快的查询。
最棒的是:
您不需要更改您的SQL :)
如果您启用了查询重写,Oracle数据库可以自动使用它。请注意查询的计划如何具有 “MAT_VIEW REWRITE ACCESS FULL” 并且仅处理43行 (A行列):
此外,如果您期望具有总和> 100的帐户数量为 “小”,则可以在MV中的此列上创建索引。数据库可以使用它。
但是要做到这一点,MV必须 “新鲜”。也就是说,存储在其中的数据必须与基表中的数据完全匹配。
添加一行,就会出现不匹配的情况。所以它再次访问该表:
注意第3行中T的全扫描如何访问73,096行?这将需要比43更多的精力来处理...
所以你需要保持最新。理想情况下,通过定义物化视图日志。并使其 “提交时快速刷新”。
或者,如果您有幸12.2使用 “启用查询计算” 子句创建实时具体化视图:
https://blogs.oracle.com/sql/12-things-developers-will-love-about-oracle-database-12c-release-2#real-time-mv
但是有一个技巧可用:
物化视图!
这些存储查询的结果。如果每个帐户在表中有 “许多” 行,这可以大大减少您处理的行数。而且,其他一切都相等,更少的行 => 更快的查询。
最棒的是:
您不需要更改您的SQL :)
如果您启用了查询重写,Oracle数据库可以自动使用它。请注意查询的计划如何具有 “MAT_VIEW REWRITE ACCESS FULL” 并且仅处理43行 (A行列):
create table t as
select owner accountno,
trunc( created ) as tran_date,
object_id as amount
from all_objects;
create materialized view mv
enable query rewrite as
select accountno,
count(*) ct,
sum( amount ) sm
from t
group by accountno;
set serveroutput off
select /*+ gather_plan_statistics */accountno
from t
group by accountno
having sum( amount ) > 1000;
select *
from table(dbms_xplan.display_cursor(null, null, 'ROWSTATS LAST'));
PLAN_TABLE_OUTPUT
SQL_ID 74naf2w6wvqh1, child number 0
-------------------------------------
select /*+ gather_plan_statistics */accountno from t group by
accountno having sum( amount ) > 1000
Plan hash value: 572630632
------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows |
------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 43 |
|* 1 | MAT_VIEW REWRITE ACCESS FULL| MV | 1 | 43 | 43 |
------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("MV"."SM">1000)此外,如果您期望具有总和> 100的帐户数量为 “小”,则可以在MV中的此列上创建索引。数据库可以使用它。
但是要做到这一点,MV必须 “新鲜”。也就是说,存储在其中的数据必须与基表中的数据完全匹配。
添加一行,就会出现不匹配的情况。所以它再次访问该表:
insert into t values ('CHRIS', sysdate, 1);
commit;
select /*+ gather_plan_statistics */accountno
from t
group by accountno
having sum( amount ) > 1000;
select *
from table(dbms_xplan.display_cursor(null, null, 'ROWSTATS LAST'));
PLAN_TABLE_OUTPUT
SQL_ID 74naf2w6wvqh1, child number 1
-------------------------------------
select /*+ gather_plan_statistics */accountno from t group by
accountno having sum( amount ) > 1000
Plan hash value: 1381620754
---------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows |
---------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 43 |
|* 1 | FILTER | | 1 | | 43 |
| 2 | HASH GROUP BY | | 1 | 1 | 43 |
| 3 | TABLE ACCESS FULL| T | 1 | 73095 | 73096 |
---------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(SUM("AMOUNT")>1000)注意第3行中T的全扫描如何访问73,096行?这将需要比43更多的精力来处理...
所以你需要保持最新。理想情况下,通过定义物化视图日志。并使其 “提交时快速刷新”。
或者,如果您有幸12.2使用 “启用查询计算” 子句创建实时具体化视图:
https://blogs.oracle.com/sql/12-things-developers-will-love-about-oracle-database-12c-release-2#real-time-mv
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




