Please start any new threads on our new
site at https://forums.sqlteam.com. We've got lots of great SQL Server
experts to answer whatever question you can come up with.
| Author |
Topic |
|
dshoaf
Starting Member
3 Posts |
Posted - 2004-04-16 : 14:15:39
|
| I have two large tables (3.7M and 8M records) that I am joining and searching. The fields that I am joining on and searching are all keyed. I still get table scans. Is this a problem with the size of the tables, or am I doing something wrong? The query is:SELECT CD.Total_ChargeFROM ada_data.dbo.Claim_Header CH INNER JOIN ada_data.dbo.Claim_Detail CD ON CH.Claim_Number = CD.Claim_Number AND CH.Worksheet_Number = CD.Worksheet_Number WHERE CH.Group_Number = @group AND CH.Benefit_Type = 'M' AND CH.Claim_Status_Acct = 'f' AND CH.Claim_Status_Stats = 'f' AND (CH.Paid_Date >= @fromDate AND CH.Paid_Date <= @thruDate)AND CD.Inel_Code <> '02' Thanks,Dave |
|
|
gpl
Posting Yak Master
195 Posts |
Posted - 2004-04-16 : 14:20:13
|
| can I be the first to sayplease post the DDL for your tables, it makes it so much easierone observation though the clause CD.Inel_Code <> '02' could be the culprit - as I understand it, negative conditions have a heavy impact on performanceGraham |
 |
|
|
dshoaf
Starting Member
3 Posts |
Posted - 2004-04-16 : 15:04:40
|
| Is this what you are looking for? (I'm not sure how to get the DDL, I generated a SQL create script)CREATE TABLE [dbo].[Claim_Detail] ( [Claim_Number] [char] (8) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL , [Worksheet_Number] [char] (2) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL , [Total_Charge] [numeric](9, 2) NOT NULL , [Inel_Code] [char] (2) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ) ON [PRIMARY]GO CREATE INDEX [IX_Claim_Detail_Claim_Number] ON [dbo].[Claim_Detail]([Claim_Number]) WITH FILLFACTOR = 90 ON [PRIMARY]GO CREATE INDEX [IX_Claim_Detail_Worksheet_Number] ON [dbo].[Claim_Detail]([Worksheet_Number]) WITH FILLFACTOR = 90 ON [PRIMARY]GO CREATE INDEX [IX_Claim_Detail_voidDate] ON [dbo].[Claim_Detail]([Void_Date]) WITH FILLFACTOR = 90 ON [PRIMARY]GO CREATE INDEX [IX_Claim_Detail_inelCode] ON [dbo].[Claim_Detail]([Inel_Code]) WITH FILLFACTOR = 90 ON [PRIMARY]GO CREATE INDEX [IX_Claim_Detail_Ineligible] ON [dbo].[Claim_Detail]([Ineligible]) WITH FILLFACTOR = 90 ON [PRIMARY]GO CREATE INDEX [IX_Claim_Detail_Amt_Pd_Claimant] ON [dbo].[Claim_Detail]([Amt_Pd_Claimant]) WITH FILLFACTOR = 90 ON [PRIMARY]GO CREATE INDEX [IX_Claim_Detail_Amt_Pd_Provider] ON [dbo].[Claim_Detail]([Amt_Pd_Provider]) WITH FILLFACTOR = 90 ON [PRIMARY]GO CREATE INDEX [IX_Claim_Detail_Benefit_Code] ON [dbo].[Claim_Detail]([Benefit_Code]) WITH FILLFACTOR = 90 ON [PRIMARY]GO CREATE INDEX [IX_Claim_Detail_Cov_Anal_Code] ON [dbo].[Claim_Detail]([Cov_Anal_Code]) WITH FILLFACTOR = 90 ON [PRIMARY]GOCREATE TABLE [dbo].[Claim_Header] ( [Group_Number] [char] (8) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL , [Claim_Number] [char] (8) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL , [Worksheet_Number] [char] (2) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL , [Benefit_Type] [char] (2) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL , [Claim_Status_Acct] [char] (1) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL , [Claim_Status_Stats] [char] (1) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL , [Paid_Date] [numeric](10, 0) NOT NULL ,) ON [PRIMARY]GO CREATE INDEX [IX_Claim_Header] ON [dbo].[Claim_Header]([Group_Number]) WITH FILLFACTOR = 90 ON [PRIMARY]GO CREATE INDEX [IX_Claim_Header_ClaimNumber] ON [dbo].[Claim_Header]([Claim_Number]) WITH FILLFACTOR = 90 ON [PRIMARY]GO CREATE INDEX [IX_Claim_Header_WorksheetNumber] ON [dbo].[Claim_Header]([Worksheet_Number]) WITH FILLFACTOR = 90 ON [PRIMARY]GO CREATE INDEX [IX_Claim_Header_BenefitType] ON [dbo].[Claim_Header]([Benefit_Type]) ON [PRIMARY]GO CREATE INDEX [IX_Claim_Header_ClaimStatusStat] ON [dbo].[Claim_Header]([Claim_Status_Stats]) ON [PRIMARY]GO CREATE INDEX [IX_Claim_Header_ClaimStatusAcct] ON [dbo].[Claim_Header]([Claim_Status_Acct]) ON [PRIMARY]GO CREATE INDEX [IX_Claim_Header_Diagnosis_Code] ON [dbo].[Claim_Header]([Diagnosis_Code]) WITH FILLFACTOR = 90 ON [PRIMARY]GO CREATE INDEX [IX_Claim_Header_GN] ON [dbo].[Claim_Header]([Group_Number]) ON [PRIMARY]GO CREATE INDEX [IX_Claim_Header_Paid_Date] ON [dbo].[Claim_Header]([Paid_Date]) ON [PRIMARY]GO CREATE INDEX [IX_Claim_Header_Internal_Employee_Number] ON [dbo].[Claim_Header]([Internal_Employee_Number]) WITH FILLFACTOR = 90 ON [PRIMARY]GO CREATE INDEX [IX_Claim_Header_Dependent_Code] ON [dbo].[Claim_Header]([Dependent_Code]) WITH FILLFACTOR = 90 ON [PRIMARY]GO CREATE INDEX [IX_Claim_Header_Plan] ON [dbo].[Claim_Header]([Plan]) WITH FILLFACTOR = 90 ON [PRIMARY]GO CREATE INDEX [IX_Claim_Header_Plan_Revision] ON [dbo].[Claim_Header]([Plan_Revision]) WITH FILLFACTOR = 90 ON [PRIMARY]GOI changed the <> to = (just to test it) and I still get a table scan.Thanks,Dave |
 |
|
|
gpl
Posting Yak Master
195 Posts |
Posted - 2004-04-16 : 16:33:28
|
| DaveI would be inclined to create an index with all of the columns relevant to your query in - depending on your data, the most important - ie first - column being the one that would restrict your search the greatest - the Paid_Date would be a good candidate - something like thisCREATE INDEX [IX_Main_Query] ON [dbo].[Claim_Header](Paid_Date,Group_Number,Benefit_Type,Claim_Status_Acct,Claim_Status_Stats,Worksheet_Number) WITH FILLFACTOR = 90 ON [PRIMARY]Changing the date comparison to this may also give a performance benefit(CH.Paid_Date BETWEEN @fromDate AND @thruDate) AND ......Graham |
 |
|
|
dshoaf
Starting Member
3 Posts |
Posted - 2004-04-26 : 15:30:04
|
| Sorry for the delay in my response. I found somewhat of a solution and I thought I would post it here. (I would be interested if anyone has any idea why this works better.) Every field that is queried on or joined has been indexed. I was playing with the query to see if I could find exactly what field was causing the problem, and I removed claim_detail (which is the biggest table) and the table scans were gone. I put that query into ()'s and then joined it to claim_detail so I had the following:SELECTCD.Total_ChargeFROM Claim_Detail CD inner join (SELECT CH.Claim_Number, CH.Worksheet_Number FROM ada_data.dbo.Claim_Header WHERE CH.Group_Number = @group AND CH.Benefit_Type = 'M' AND CH.Claim_Status_Acct = 'f' AND CH.Claim_Status_Stats = 'f' AND (CH.Paid_Date >= @fromDate AND CH.Paid_Date <= @thruDate)) as Aon A.Claim_Number = CD.Claim_Number ANDA.Worksheet_Number = CD.Worksheet_Number WHERECD.Inel_Code <> '02'which still had tables scans until I added grouping. (I'm not sure why the grouping helped.)SELECTsum(CD.Total_Charge)FROM Claim_Detail CD inner join (SELECT CH.Claim_Number, CH.Worksheet_Number FROM ada_data.dbo.Claim_Header WHERE CH.Group_Number = @group AND CH.Benefit_Type = 'M' AND CH.Claim_Status_Acct = 'f' AND CH.Claim_Status_Stats = 'f' AND (CH.Paid_Date >= @fromDate AND CH.Paid_Date <= @thruDate)) as Aon A.Claim_Number = CD.Claim_Number ANDA.Worksheet_Number = CD.Worksheet_Number WHERECD.Inel_Code <> '02'group by cd.claim_number, cd.worksheet_number, cd.line_number, cd.line_counter, cd.line_number_dupe, CD.Inel_Code, CD.Cov_Anal_Code, CD.Benefit_CodeNow magically my table scans are gone, and it now finishes in 1 minute instead of > 8 mins. It seems that it was joining the two tables before it applies the where clause.(just my guess.)Thanks,Dave |
 |
|
|
|
|
|
|
|