Hi
I have an database with a main table containing 72 million rows.
The application is a Patient Information System, or rather a data warehouse for data from
several PIS. The data is used as an overview for the specific patient beeing treated, it is not used
for statistical reports.
Then there are four details tables related to the main table by a FK.
Selections work fine up to a few thousand rows but when the time approaches
30 seconds, the default timeout for db commands from .NET. Increasing the timeout would fix the
problem temporarily but I would like to explore any alternative solution first.
Selections that take a minute the first time they are exeuted take a few seconds if executed againd
due to the caching of pages in SQL Server (or Windows?).
Running a selection on the main table
select * from Item where PatientId='100000100001'
takes a few seconds the first time too and the Query Plan reveals that the clustered index om PatientId
is used and the one execution returns say 15000 rows.
Then I join with a details table
select * from Item i
inner join Diagnosis d on i.id=d.itemid where i.PatientId='100000100001'
and the clustered index om Item.PatientId is selected and the clustered index on
Diagnosis.itemid is also selected. Since the itemids are scatterd all over the range of Item.id:s
the clustered index is seeked 15000 times returning on row each.
This takes a lot of time the first time the query is executed but a few seconds next time (same params).
I guess this has to do with the 15000 separate disk accesses that results from the clustered index seek
on Diagnosis.
Adding the PatientId to the Diagnosis table as well, and having the clustered index on Diagnosis[PatientId,itemid]
was an impulse but that seems wrong from a normalization point of view and would complicate the other uses of the
database.
Any help appreciated!
/Ove
Tables, reduced to illustrate the problem:
CREATE TABLE [dbo].[Item]( [id] [bigint] IDENTITY(1,1) NOT NULL, [PatientId] [varchar](255) NOT NULL, [ItemDate] [datetime] NOT NULL, CONSTRAINT [PK_Item] PRIMARY KEY NONCLUSTERED ( [id] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] CREATE TABLE [dbo].[Diagnosis]( [did] [bigint] IDENTITY(1,1) NOT NULL, [Disease] [varchar](255) NOT NULL, [itemid] [bigint] NOT NULL, CONSTRAINT [PK_Diagnosis] PRIMARY KEY NONCLUSTERED ( [did] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] ALTER TABLE [dbo].[Diagnosis] WITH CHECK ADD CONSTRAINT [FK_Diagnosis_Item] FOREIGN KEY([itemid]) REFERENCES [dbo].[Item] ([id]) ALTER TABLE [dbo].[Diagnosis] CHECK CONSTRAINT [FK_Diagnosis_Item]