我的应用程序正在尝试执行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
有人可以解释发生了什么吗?如何提高查询的性能?感谢。
答案 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
如何使用解释计划语法(以及查询以查看结果。)
如果没有表现出任何可疑之处,你可能想要查看一下。