Oracle sql查询(几乎)永远运行

时间:2010-08-19 18:41:10

标签: sql oracle

我的应用程序正在尝试执行count(*)查询,该查询在大约30分钟后返回。奇怪的是,查询非常简单,涉及的表很大,但不是很大(10,000和50,000条记录)。

需要30分钟的查询是:

select count(*) 
from RECORD r inner join GROUP g 
  on g.GROUP_ID = r.GROUP_ID 
where g.BATCH_ID = 1 and g.ENABLED = 'Y'

数据库架构基本上是:

create table BATCH (
    BATCH_ID int not null,
    [other columns]...,
    CONSTRAINT PK_BATCH PRIMARY KEY (BATCH_ID)
);

create table GROUP (
    GROUP_ID int not null,
    BATCH_ID int,
    ENABLED char(1) not null,
    [other columns]...,
    CONSTRAINT PK_GROUP PRIMARY KEY (GROUP_ID),
    CONSTRAINT FK_GROUP_BATCH_ID FOREIGN KEY (BATCH_ID)
        REFERENCES BATCH (BATCH_ID),
    CONSTRAINT CHK_GROUP_ENABLED CHECK(ENABLED in ('Y', 'N'))
);

create table RECORD (
    GROUP_ID int not null, 
    RECORD_NUMBER int not null,
    [other columns]...,
    CONSTRAINT PK_RECORD PRIMARY KEY (GROUP_ID, RECORD_NUMBER),
    CONSTRAINT FK_RECORD_GROUP_ID FOREIGN KEY (GROUP_ID)
        REFERENCES GROUP (GROUP_ID)
);

create index IDX_GROUP_BATCH_ID on GROUP(BATCH_ID);

我检查了数据库中是否有任何块,但没有。我还运行了以下查询部分,除了最后两个之外的所有部分立即返回:

select count(*) from RECORD -- 55,501

select count(*) from GROUP -- 11,693

select count(*) 
from RECORD r inner join GROUP g 
  on g.GROUP_ID = r.GROUP_ID
-- 55,501

select count(*) 
from GROUP g 
where g.BATCH_ID = 1 and g.ENABLED = 'Y' 
-- 3,112

select count(*) 
from RECORD r inner join GROUP g 
  on g.GROUP_ID = r.GROUP_ID 
where g.BATCH_ID = 1 
-- 27,742 - took around 5 minutes to run

select count(*) 
from RECORD r inner join GROUP g 
  on g.GROUP_ID = r.GROUP_ID 
where g.ENABLED = 'Y' 
-- 51,749 - took around 5 minutes to run

有人可以解释发生了什么吗?如何提高查询的性能?感谢。

3 个答案:

答案 0 :(得分:1)

一位同事发现了这个问题。这是因为表统计信息没有更新,上次分析表是在几个月前(当表基本上是空的时)。我运行了分析表RECORD计算统计信息,现在查询在不到一秒的时间内返回。

我将不得不与DBA讨论为什么表统计信息没有更新。

答案 1 :(得分:0)

SELECT COUNT(*)  
FROM   RECORD R
LEFT OUTER JOIN GROUP G ON G.GROUP_ID = R.GROUP_ID  
       AND G.BATCH_ID = 1
       AND G.ENABLED = 'Y'

尝试一下,让我知道结果如何。不是说这是答案,但由于我现在无法访问数据库,我无法测试它。希望它适用于你。

答案 2 :(得分:0)

解释计划将是一个很好的起点。

见这里:

Strange speed changes with sql query

如何使用解释计划语法(以及查询以查看结果。)

如果没有表现出任何可疑之处,你可能想要查看一下。