Oracle 甲骨文:加速计数(*)?
我有一个应用程序正在与cake/php组合在一起。它是 很不错,但他们的数据寻呼机可以做到:Oracle 甲骨文:加速计数(*)?,oracle,Oracle,我有一个应用程序正在与cake/php组合在一起。它是 很不错,但他们的数据寻呼机可以做到: SELECT COUNT(*) AS COUNT FROM foo f LEFT JOIN bar b ON (f.asset_group_id = b.asset_group_id) WHERE 1 = 1 有没有办法加快速度 更新:删除了表定义的额外列: create table bar ( last_modified_by varchar2(1
SELECT COUNT(*) AS COUNT
FROM foo f
LEFT JOIN bar b
ON (f.asset_group_id = b.asset_group_id)
WHERE 1 = 1
有没有办法加快速度
更新:删除了表定义的额外列:
create table bar (
last_modified_by varchar2(16),
asset_group_id number(10,0) not null enable,
folder varchar2(512) not null enable,
name varchar2(512) not null enable,
kind varchar2(16),
-- exta fields deleted
constraint bar_pk primary key (folder, name) enable
);
create index bar_last_modified_date on bar (last_modified_date desc) ;
create index bar_asset_group_id on bar (asset_group_id desc) ;
create index bar_folder on bar (folder) ;
create index bar_kind on bar (kind) ;
create unique index bar_pk on bar (folder, name) ;
create table foo (
created_date date not null enable,
asset_group_id number(10,0) not null enable,
keyword varchar2(4000) not null enable,
-- exta fields deleted
constraint foo_pk primary key (asset_group_id, keyword) enable
) enable row movement ;
create index foo_created on foo (created_date desc) ;
create unique index foo_pk on foo (asset_group_id, keyword) ;
实际上,没有任何方法可以修改SQL以使其更快—它已经是一个相当基本的查询。您可能可以修改表本身的索引等方面,但SQL本身是您可以获得所需信息的最有效表示形式。请确保f.asset\u group\u id和b.asset\u group\u id已被索引 我相信,在Oracle中,内部count*和count1的作用是相同的 问候 K
另外,如果你已经有了企业版,你可以在f.asset\u group\u id,b.asset\u group\u id上创建一个位图连接索引,以实现真正的查找速度:-如果你在两个asset\u group\u id列上都没有索引,那么是时候构建一些了。为了加快速度,尝试将Count*替换为CountColumnNo1,ColumnNo2,。。。,其中使用的星号可能是减速,因为数据库每次都必须计算出星号的含义……通过在sql中包含特定的列名,您可以有效地减轻数据库计算该表中使用的列的负担 希望这有帮助, 顺致敬意,
Tom.取决于数据,即foo.asset\u group\u id和bar.asset\u group\u id之间的相关性。您需要检查计划以查看哪个表驱动查询,它使用的是什么联接方法。例如,如果其中一个表比另一个表小一个数量级,则最好使用散列联接,而不是嵌套循环+索引查找。另一个选项,特别是如果两个表都非常大,则是排序合并,并在两个资产组id列上提供适当的索引。如果对foo和bar进行了索引,并且两个表都有最新的统计信息,则count*通常会以最有效的方式返回行计数 也许它只是一个大表,在这种情况下,在分页浏览表内容之前获取完整的最新行计数将非常昂贵 解决这个问题的两种方法: 不要担心结果有多少页——第1页(共3439页)并不比第1页(共3439页)有用多少 预先计算结果,并根据需要定期更新。例如,如果行计数为24小时,是否可以
在提供任何有用的答案之前,您确实需要更多关于表格设计的信息。该查询包含一个外部联接,如果资产组id是bar的主键,则该联接甚至不是必需的。。。。但是,没有表定义就无法知道。具体化视图可能会有所帮助。同样,这可能会减慢对基础表的插入速度,如果有大量插入,这可能是一个问题。您确实有涉及资产组ID的索引,但其中一个是降序索引,另一个也是由关键字列组成的。让我们询问Oracle查询计划器在查询中是否使用了这些选项:
EXPLAIN SELECT COUNT(*) ...
如果你能发布这些结果,那会给我们很多信息
如果您当前的索引未被使用,我希望这些索引能够正常工作:
create index bar_asset_group_id on bar (asset_group_id);
create index foo_asset_group_id on foo (asset_group_id);
为清晰起见,请将当前条形图资源组id重命名为条形图资源组id描述
删除其中的1=1:这几乎是完全无害的,但非常不必要。您可以使用嵌套在另一个快速刷新物化视图上的快速刷新物化视图 我插入样本数据
create table bar (
last_modified_by varchar2(16),
asset_group_id number(10,0) not null enable,
folder varchar2(512) not null enable,
name varchar2(512) not null enable,
-- exta fields deleted
constraint bar_pk primary key (folder, name) enable
);
create index bar_asset_group_id on bar (asset_group_id desc) ;
create index bar_folder on bar (folder) ;
create index bar_kind on bar (kind) ;
insert into bar values ('deew',1,'A','B');
insert into bar values ('deew',1,'A','C');
insert into bar values ('deew',1,'B','C');
insert into bar values ('deew',2,'E','C');
commit;
create table foo (
created_date date not null enable,
asset_group_id number(10,0) not null enable,
keyword varchar2(4000) not null enable,
-- exta fields deleted
constraint foo_pk primary key (asset_group_id, keyword) enable
) enable row movement ;
insert into foo values (sysdate,1,'dd');
insert into foo values (sysdate,2,'dd');
insert into foo values (sysdate,3,'dd');
insert into foo values (sysdate,1,'ddE');
commit;
create index foo_created on foo (created_date desc) ;
create materialized view log on bar with rowid including new values;
create materialized view log on foo with rowid including new values;
create materialized view foobar_count_helper
refresh fast on commit
as
select f.rowid rowid_f
, b.rowid rowid_b
from foo f
, bar b
where f.asset_group_id = b.asset_group_id (+)
/
create materialized view log on foobar_count_helper with rowid including new values;
create materialized view foobar_count
refresh fast on commit
as
select count(*) count
from foobar_count_helper
/
测试结果:
SQL>
SQL>
SQL> select * from foobar_count;
COUNT
----------
8
SQL>
SQL> SELECT COUNT(*) AS COUNT
2 FROM foo f
3 LEFT JOIN bar b
4 ON (f.asset_group_id = b.asset_group_id)
5 where 1=1
6 /
COUNT
----------
8
在确定它是否可加速之前,需要知道你有哪些索引,以及执行计划是什么。@Tordek:因为它比2+2=4的地方快-你能把表格的定义贴出来吗?具体来说,我需要知道这些列是否定义为NULL,它们是唯一的还是主键,它们是外键约束的一部分。除了向下投票之外,还要从表中删除所有数据。关于这是一个坏主意的原因的评论是一个好主意。Oracle的优化器非常聪明,知道COUNT*的结果始终与COUNT1或COUNT相同。如果您想要行数,请使用COUNT*。Oracle将寻找返回结果的最有效方式,使用并行FTS、对非空列的快速完整索引扫描、实体化视图、缓存值或其他任何方式。国会预算办公室相当聪明。