Re: Query execution plan different between production/test - same
From: Aaron (Aaron_at_discussions.microsoft.com)
Date: 07/28/04
- Next message: Aaron: "Re: Query execution plan different between production/test - same"
- Previous message: CD: "Access vs SQL"
- In reply to: Andrew J. Kelly: "Re: Query execution plan different between production/test - same data"
- Next in thread: Aaron: "Re: Query execution plan different between production/test - same"
- Messages sorted by: [ date ] [ thread ]
Date: Wed, 28 Jul 2004 06:15:06 -0700
2) Tweaked Query and execution plan on Prod server that runs fast:
SELECT
Shifts.dtShiftDate,
Shifts.chMachineID,
Shifts.siShiftNo,
Shifts.vchOperation,
Parts.vchPlatform,
Parts.vchOpening,
Parts.vchPlatform+' '+vchopening,
rtrim(parts.vchdescription)+' - '+rtrim(ltrim(Parts.chPartID)),
Shifts.intPressCycles,
Shifts.intPressCycles*bitIncludeInMachineHrs,
intPressCycles*bitIncludeInMachineHrs*bitIncludePressCycles,
Shifts.intTimeDown,
Shifts.intScrap, Shifts.intRings,
60*MachineHrs/intCycleTimeGoal*(ftYieldGoal/100)*(ftUptimeGoal/100)*bitIncludeinMachineHrs*bitIncludePressCycles,
60*MachineHrs/intCycleTimeGoal*(ftYieldGoal/100)*(ftUptimeGoal/100)*bitIncludeinMachineHrs,
60*MachineHrs/PartMetrics.intCycleTimeBud*(PartMetrics.ftYieldBud/100)*(PartMetrics.ftUptimeBud/100)*bitIncludeInMachineHrs*bitIncludePressCycles,
60*MachineHrs/PartMetrics.intCycleTimeBud*(PartMetrics.ftYieldBud/100)*(PartMetrics.ftUptimeBud/100)*bitIncludeInMachineHrs,
ltrim(datepart(month,dtshiftdate))+' - '+rtrim(datepart(year,dtshiftdate)),
Shifts.OperatorTimeMins,
Shifts.MachineHrs*bitIncludeInMachineHrs,
(Shifts.intPressCycles*bitIncludeInMachineHrs-intRings)*(1-ftyieldgoal/100),
(intPressCycles*bitIncludeInMachineHrs-intRings)*(1-PartMetrics.ftYieldBud/100),
MachineHrs*(1-PartMetrics.ftUptimeBud/100)*bitIncludeInMachineHrs,
PartMetrics.ftCrewSizeBud,
PartMetrics.intCycleTimeBud,
Parts.intCycleTimeGoal,
PartMetrics.ftYieldBud,
Parts.ftYieldGoal,
PartMetrics.ftUptimeBud,
Parts.ftUptimeGoal,
Parts.ftCrewSizeGoal,
ftCrewSizeBud*MachineHrs*bitIncludeInMachineHrs,
ftCrewSizeGoal*MachineHrs*bitIncludeInMachineHrs,
MachineHrs*(1-ftUptimeGoal/100)*bitIncludeInMachineHrs,
Shifts.dtShiftDate-datepart(w,dtShiftDate-1)+1,
PartMachineAvailability.bitIncludePressCycles
FROM ShopFloor.dbo.Operations Operations
INNER JOIN ShopFloor.dbo.vShifts Shifts ON Operations.vchOperation = Shifts.vchOperation AND Shifts.vchOperation<>'DEVELOPMENT'
INNER JOIN ShopFloor.dbo.Parts Parts ON Parts.chPartID = Shifts.chPartID
INNER JOIN ShopFloor.dbo.PartMetrics PartMetrics ON PartMetrics.chPartID = Shifts.chPartID AND (PartMetrics.dtMonthYear=dtshiftdate-datepart(day,dtShiftDate)+1)
INNER JOIN ShopFloor.dbo.PartMachineAvailability PartMachineAvailability
ON (PartMachineAvailability.chMachineID = Shifts.chMachineID AND PartMachineAvailability.chPartID = Shifts.chPartID)
WHERE (Shifts.dtShiftDate>dateadd(m,-5,getdate()-datepart(d,getdate())+1)-1)
ORDER BY Shifts.dtShiftDate, Shifts.chMachineID
--------------------------------------------------------------------------------------------
|--Compute Scalar(DEFINE:([Expr1043]=[Parts].[vchPlatform]+' '+[Parts].[vchOpening], [Expr1044]=rtrim([Parts].[vchDescription])+' - '+rtrim(ltrim(Convert([Parts].[chPartID]))), [Expr1045]=[Shifts].[intPressCycles]*Convert([Operations].[bitIncludeInMachin
|--Sort(ORDER BY:([Shifts].[dtShiftDate] ASC, [Shifts].[chMachineID] ASC))
|--Compute Scalar(DEFINE:([Expr1027]=isnull([Shifts].[intTimeDown], 0), [Expr1028]=isnull([Shifts].[intScrap], 0), [Expr1029]=isnull([Shifts].[intRings], 0), [Expr1032]=[Expr1032], [Expr1040]=If (Convert([Operations].[bitIncludeInMachineHrs])=1
|--Nested Loops(Inner Join, OUTER REFERENCES:([Shifts].[chPartID], [Shifts].[dtShiftDate]) WITH PREFETCH)
|--Hash Match(Inner Join, HASH:([PartMachineAvailability].[chPartID], [PartMachineAvailability].[chMachineID])=([Shifts].[chPartID], [Shifts].[chMachineID]), RESIDUAL:([Shifts].[chPartID]=[PartMachineAvailability].[chPartID] AND [Part
| |--Clustered Index Scan(OBJECT:([ShopFloor].[dbo].[PartMachineAvailability].[PK_PartMachineAvailability] AS [PartMachineAvailability]))
| |--Hash Match(Inner Join, HASH:([Parts].[chPartID])=([Shifts].[chPartID]), RESIDUAL:([Parts].[chPartID]=[Shifts].[chPartID]))
| |--Clustered Index Scan(OBJECT:([ShopFloor].[dbo].[Parts].[PK__Parts__7D78A4E7] AS [Parts]))
| |--Hash Match(Inner Join, HASH:([Operations].[vchOperation])=([Shifts].[vchOperation]), RESIDUAL:([Operations].[vchOperation]=[Shifts].[vchOperation]))
| |--Clustered Index Scan(OBJECT:([ShopFloor].[dbo].[Operations].[PK__Operations__76969D2E] AS [Operations]))
| |--Nested Loops(Inner Join, WHERE:(IsFalseOrNull(Convert([Operations].[bitIncludeInMachineHrs])=1))OUTER REFERENCES:([Shifts].[chShiftID]))
| |--Hash Match(Right Outer Join, HASH:([OperatorLogins].[chShiftID])=([Shifts].[chShiftID]), RESIDUAL:([OperatorLogins].[chShiftID]=[Shifts].[chShiftID]))
| | |--Compute Scalar(DEFINE:([Expr1032]=If ([Expr1102]=0) then NULL else [Expr1103]))
| | | |--Hash Match(Aggregate, HASH:([OperatorLogins].[chShiftID]), RESIDUAL:([OperatorLogins].[chShiftID]=[OperatorLogins].[chShiftID]) DEFINE:([Expr1102]=COUNT_BIG(datediff(minute, [OperatorLogins].[dtLogin],
| | | |--Clustered Index Scan(OBJECT:([ShopFloor].[dbo].[OperatorLogins].[PK_OperatorLogins]), WHERE:([OperatorLogins].[dtLogout]<>NULL))
| | |--Hash Match(Right Outer Join, HASH:([Operations].[vchOperation])=([Shifts].[vchOperation]), RESIDUAL:([Operations].[vchOperation]=[Shifts].[vchOperation]))
| | |--Clustered Index Scan(OBJECT:([ShopFloor].[dbo].[Operations].[PK__Operations__76969D2E]))
| | |--Hash Match(Right Outer Join, HASH:([PartMetrics].[chPartID], [PartMetrics].[dtMonthYear])=([Shifts].[chPartID], [Expr1100]), RESIDUAL:([PartMetrics].[chPartID]=[Shifts].[chPartID] AND [PartMetrics].[dt
| | |--Clustered Index Scan(OBJECT:([ShopFloor].[dbo].[PartMetrics].[PK__PartMetrics__1CBC4616]))
| | |--Compute Scalar(DEFINE:([Expr1100]=dateadd(day, -datepart(day, Convert([Shifts].[dtShiftDate]))+1, [Shifts].[dtShiftDate])))
| | |--Hash Match(Right Outer Join, HASH:([Union1021])=([Shifts].[intShiftCoordinator]), RESIDUAL:([Union1021]=[Shifts].[intShiftCoordinator]))
| | |--Sort(DISTINCT ORDER BY:([Union1018] ASC, [Union1019] ASC, [Union1020] ASC, [Union1021] ASC, [Union1022] ASC, [Union1023] ASC))
| | | |--Concatenation
| | | |--Compute Scalar(DEFINE:([Expr1012]=rtrim([Employees].[FirstName])+' '+[Employees].[LastName], [Expr1013]=Convert([Employees].[Emp #])+replicate('*', 18-len(Convert([Employees].[
| | | | |--Clustered Index Scan(OBJECT:([ShopFloor].[dbo].[Employees].[PK_Employees]), WHERE:(Convert([Employees].[Terminated])<>1))
| | | |--Compute Scalar(DEFINE:([Expr1016]=rtrim([IntroAssociates].[FName])+' '+[IntroAssociates].[LName], [Expr1017]=Convert([IntroAssociates].[TempID])+replicate('*', 18-len(Convert([
| | | |--Clustered Index Scan(OBJECT:([ShopFloor].[dbo].[IntroAssociates].[PK_IntroAssociates]), WHERE:([IntroAssociates].[Status]='Interim'))
| | |--Clustered Index Scan(OBJECT:([ShopFloor].[dbo].[Shifts].[PK__Shifts__0425A276]), WHERE:([Shifts].[vchOperation]<>'DEVELOPMENT' AND Convert([Shifts].[dtShiftDate])>dateadd(month, -5, getd
| |--Hash Match(Cache, HASH:([Shifts].[chShiftID]), RESIDUAL:([Shifts].[chShiftID]=[Shifts].[chShiftID]))
| |--Stream Aggregate(DEFINE:([Expr1037]=MAX([OperatorLogins].[dtLogout]), [Expr1038]=MIN([OperatorLogins].[dtLogin])))
| |--Index Spool(SEEK:([OperatorLogins].[chShiftID]=[Shifts].[chShiftID]))
| |--Clustered Index Scan(OBJECT:([ShopFloor].[dbo].[OperatorLogins].[PK_OperatorLogins]))
|--Clustered Index Seek(OBJECT:([ShopFloor].[dbo].[PartMetrics].[PK__PartMetrics__1CBC4616] AS [PartMetrics]), SEEK:([PartMetrics].[chPartID]=[Shifts].[chPartID] AND [PartMetrics].[dtMonthYear]=[Shifts].[dtShiftDate]-Convert(datepart(
"Andrew J. Kelly" wrote:
> Can you show the query? You say you tweaked it? How did you do that? Is
> the data the exact same on both machines? What does the query plan look like
> for the slow one compared to the fast one?
>
> --
> Andrew J. Kelly SQL MVP
>
>
> "Aaron" <Aaron@discussions.microsoft.com> wrote in message
> news:33F423DF-1D9C-4227-B1F4-2CAF5142BD9C@microsoft.com...
> > I have a query that runs much much slower on my production server than my
> test server. By tweaking the query I can make it run fast in production. Why
> can't I make prod act like test? The difference in execution time is 15
> minutes! (test - 5 seconds/prod - 15 minutes). I need to make PROD more like
> TEST, or at least TEST should be slower than PROD (what is the point of load
> testing?)
> >
> > My test server has the same SQL version/patch level and OS version/patch
> level as my production server. The data is a replica. The query execution
> plans are different. The production server has more ram, faster CPUs (dual),
> and faster disk. Production is under light utilization (<20%). It is
> reindexed each night. I have updated statistics on all tables involved. I
> ran a server configuration and schema configuration comparison with RedGate
> software and all items are indenticle (save ram/cpu/names of jobs). The prod
> server has 2 cpu so I tried restricting parallelism to 1. When the slow
> query runs on production it chews one of the CPU's @50% for all 15 minutes.
> The problem has slowly gotten worse of the past month. The database is only
> 120mb and is the only db so far on this server. The DB server is dedicated,
> there are no other uses for it. Its paired app server is under very low
> utilization also. As I said, by tweaking the query the query time goes from
> 15 minutes down to 4 seconds without changing the result set. The main
> gotcha is that my test server runs the fast execution plan with or without
> tweaking the query. I need it to run fast without tweaking so my users can
> run ad hoc queries without me having to get involved. I know it is possible,
> look at my test box!!
> >
> > I am stumped on this performance problem. Please help if you can with any
> thoughts or suggestions for getting MSSQL to run consistant with respect to
> execution plans between my two servers. Our Oracle DBA is laughing...
> >
>
>
>
- Next message: Aaron: "Re: Query execution plan different between production/test - same"
- Previous message: CD: "Access vs SQL"
- In reply to: Andrew J. Kelly: "Re: Query execution plan different between production/test - same data"
- Next in thread: Aaron: "Re: Query execution plan different between production/test - same"
- Messages sorted by: [ date ] [ thread ]
Relevant Pages
|