June 24, 2008 at 10:38 am
The following query takes me very long to run, what is the best i can change here to boost performance.
SELECT CombinedTT.Level4Description, CombinedTT.EmployeeName, CombinedTT.PunchType,
CombinedTT.DepartmentDescript, SUM((CASE WHEN TimeType = 1 THEN RegT / 60 ELSE 0 END)) AS RegT,
SUM((CASE WHEN TimeType = 1 THEN OT / 60 ELSE 0 END)) AS OT, SUM((CASE WHEN TimeType = 1 THEN DT / 60 ELSE 0 END)) AS DT,
SUM((CASE WHEN TimeType = 2 AND PunchType <> 'V' THEN TotalTime / 60 ELSE 0 END)) AS PTO, SUM((CASE WHEN TimeType = 2 AND
PunchType <> 'V' THEN totaltime ELSE 0 END) + (CASE WHEN TimeType = 1 THEN RegT ELSE 0 END)) AS RegTotal,
SUM((CASE WHEN (PunchType = 'LE') OR
(PunchType = 'LC') THEN TotalTime / 60 ELSE (CASE WHEN TimeType <> 4 THEN AutoLunch / 60 ELSE 0 END) END)) AS AutoLunch,
SUM((CASE WHEN (((TimeType = 1)) AND ((PunchType <> 'LE') AND (PunchType <> 'LC')) OR
(TimeType = 2 AND PunchType <> 'V')) THEN TotalTime / 60 ELSE 0 END)) AS TotalTime, SUM((CASE WHEN ((TimeType = 1)) AND
((PunchType <> 'LE') AND (PunchType <> 'LC')) THEN TotalTime / 60 ELSE 0 END)) AS WorkedTime, SUM((((CASE WHEN TimeType = 2 AND
PunchType <> 'V' THEN totaltime ELSE 0 END) + (CASE WHEN TimeType = 1 THEN RegT ELSE 0 END))
+ (CASE WHEN TimeType = 1 THEN OT ELSE 0 END) * 1.5) + (CASE WHEN TimeType = 1 THEN DT ELSE 0 END) * 2) AS RTE,
SUM(CombinedTT.TotalPayDol) AS TotalPay, SUM(CombinedTT.TotalBillDol) AS TotallBill,
convert(VARCHAR(6), CombinedTT.StartTime, 112)as Period
FROM (SELECT CardID, EmployeeName, StartTime, EndTime, Autolunch, Punch, PunchType, PunchClass, HomeDivision, HomeDivisionDescript,
HomeDepartment, HomeDeptDescript, Department, DepartmentDescript, JobNumber, JobNumberDescription, Level4, Level4Description,
Level5, Level5Description, StartRounded, EndRounded, RegT, OT, DT, TotalTime, Dollars, Quantity, SchedNo, ShiftNo, ShiftNoDescript,
PayRate, TotalPayDol, BillRate, TotalBillDol, TotalDol, PayType, PayTypeDescript, ExceptionType, OTDescription, Notes, Counter, Status,
PayPeriodCode, PayPeriodDesc, LastUpdated, OtherID, Paid, AccrueToOT, TimeType, SatPremAmt, SunPremAmt, RegTComp, OTComp,
Premium1, ParentRec, Protect, DTComp, StartLocationNo, StartLocationType, StartLocationName, EndLocationNo, EndLocationType,
EndLocationName, ShiftGroupDesignator
FROM dbo.TT
UNION ALL
SELECT CardID, EmployeeName, StartTime, EndTime, Autolunch, Punch, PunchType, PunchClass, HomeDivision, HomeDivisionDescript,
HomeDepartment, HomeDeptDescript, Department, DepartmentDescript, JobNumber, JobNumberDescription, Level4, Level4Description,
Level5, Level5Description, StartRounded, EndRounded, RegT, OT, DT, TotalTime, Dollars, Quantity, SchedNo, ShiftNo, ShiftNoDescript,
PayRate, TotalPayDol, BillRate, TotalBillDol, TotalDol, PayType, PayTypeDescript, ExceptionType, OTDescription, Notes, Counter, Status,
PayPeriodCode, PayPeriodDesc, LastUpdated, OtherID, Paid, AccrueToOT, TimeType, SatPremAmt, SunPremAmt, RegTComp, OTComp,
Premium1, ParentRec, Protect, DTComp, StartLocationNo, StartLocationType, StartLocationName, EndLocationNo, EndLocationType,
EndLocationName, ShiftGroupDesignator
FROM dbo.ArchTT) AS CombinedTT INNER JOIN
dbo.EmployeeT ON CombinedTT.CardID = dbo.EmployeeT.CardID INNER JOIN
dbo.PayPeriodT ON dbo.EmployeeT.PayPeriod = dbo.PayPeriodT.PayPeriodCode
WHERE (CombinedTT.TimeType IN ('1', '2', '4')) AND (convert(VARCHAR(6), CombinedTT.StartTime, 112)= '{?Period}') AND
(CombinedTT.DepartmentDescript Like '{?ProjectName}')
GROUP BY CombinedTT.Level4Description,CombinedTT.DepartmentDescript, CombinedTT.EmployeeName, CombinedTT.PunchType, CombinedTT.StartTime
HAVING (NOT (CombinedTT.PunchType IN ('S', 'V', 'AB')))
ORDER BY CombinedTT.DepartmentDescript
June 24, 2008 at 11:36 am
Can you post the table structure, the indexes and the aprox row count please.
How long does it currently run?
If possible, can you get the exec plan (set showplan_all on), run to grid and copy everything to excel and post that here? It will help identify why the query is slow.
Gail Shaw
Microsoft Certified Master: SQL Server, MVP, M.Sc (Comp Sci)
SQL In The Wild: Discussions on DB performance with occasional diversions into recoverability
June 24, 2008 at 11:54 am
please check the atttachments for table structures.
Right now its taking more than 20min . each table has 3574385 records approx.
June 24, 2008 at 12:04 pm
Indexes? Any chance of the execution plan?
How many rows does the query return?
Gail Shaw
Microsoft Certified Master: SQL Server, MVP, M.Sc (Comp Sci)
SQL In The Wild: Discussions on DB performance with occasional diversions into recoverability
June 24, 2008 at 12:06 pm
Besides the INDEX part,
(convert(VARCHAR(6), CombinedTT.StartTime, 112)= '{?Period}')
---- this one takes longer in WHERE clause.....
Better move the CONVERT into your SELECT...UNION ALL....part
June 24, 2008 at 12:22 pm
did you try to split the "UNION ALL"
So to rewrite the full query using the TT table
and then perform a union all using the full query with the ArchTT table
does that make sence to you ?
Something like this...
SELECT CardID, EmployeeName, StartTime, EndTime, Autolunch, Punch, PunchType, PunchClass, HomeDivision, HomeDivisionDescript,
HomeDepartment, HomeDeptDescript, Department, DepartmentDescript, JobNumber, JobNumberDescription, Level4, Level4Description,
Level5, Level5Description, StartRounded, EndRounded, RegT, OT, DT, TotalTime, Dollars, Quantity, SchedNo, ShiftNo, ShiftNoDescript,
PayRate, TotalPayDol, BillRate, TotalBillDol, TotalDol, PayType, PayTypeDescript, ExceptionType, OTDescription, Notes, Counter, Status,
PayPeriodCode, PayPeriodDesc, LastUpdated, OtherID, Paid, AccrueToOT, TimeType, SatPremAmt, SunPremAmt, RegTComp, OTComp,
Premium1, ParentRec, Protect, DTComp, StartLocationNo, StartLocationType, StartLocationName, EndLocationNo, EndLocationType,
EndLocationName, ShiftGroupDesignator
FROM dbo.TT as TT
INNER JOIN
dbo.EmployeeT ON TT.CardID = dbo.EmployeeT.CardID INNER JOIN
dbo.PayPeriodT ON dbo.EmployeeT.PayPeriod = dbo.PayPeriodT.PayPeriodCode
WHERE (TT.TimeType IN ('1', '2', '4'))
AND (convert(VARCHAR(6), TT.StartTime, 112)= '{?Period}')
AND (TT.DepartmentDescript Like '{?ProjectName}')
UNION ALL
SELECT CardID, EmployeeName, StartTime, EndTime, Autolunch, Punch, PunchType, PunchClass, HomeDivision, HomeDivisionDescript,
HomeDepartment, HomeDeptDescript, Department, DepartmentDescript, JobNumber, JobNumberDescription, Level4, Level4Description,
Level5, Level5Description, StartRounded, EndRounded, RegT, OT, DT, TotalTime, Dollars, Quantity, SchedNo, ShiftNo, ShiftNoDescript,
PayRate, TotalPayDol, BillRate, TotalBillDol, TotalDol, PayType, PayTypeDescript, ExceptionType, OTDescription, Notes, Counter, Status,
PayPeriodCode, PayPeriodDesc, LastUpdated, OtherID, Paid, AccrueToOT, TimeType, SatPremAmt, SunPremAmt, RegTComp, OTComp,
Premium1, ParentRec, Protect, DTComp, StartLocationNo, StartLocationType, StartLocationName, EndLocationNo, EndLocationType,
EndLocationName, ShiftGroupDesignator
FROM dbo.ArchTT as ArchTT
INNER JOIN
dbo.EmployeeT ON ArchTT .CardID = dbo.EmployeeT.CardID INNER JOIN
dbo.PayPeriodT ON dbo.EmployeeT.PayPeriod = dbo.PayPeriodT.PayPeriodCode
WHERE (ArchTT.TimeType IN ('1', '2', '4'))
AND (convert(VARCHAR(6), ArchTT.StartTime, 112)= '{?Period}')
AND (ArchTT.DepartmentDescript Like '{?ProjectName}')
)
GROUP BY CombinedTT.Level4Description,CombinedTT.DepartmentDescript, CombinedTT.EmployeeName, CombinedTT.PunchType, CombinedTT.StartTime
HAVING (NOT (CombinedTT.PunchType IN ('S', 'V', 'AB'))
Johan
Learn to play, play to learn !
Dont drive faster than your guardian angel can fly ...
but keeping both feet on the ground wont get you anywhere :w00t:
- How to post Performance Problems
- How to post data/code to get the best help[/url]
- How to prevent a sore throat after hours of presenting ppt
press F1 for solution, press shift+F1 for urgent solution 😀
Need a bit of Powershell? How about this
Who am I ? Sometimes this is me but most of the time this is me
June 24, 2008 at 12:27 pm
pls find the attachement for execution plan.
thanks for the concern.
June 24, 2008 at 12:41 pm
Wildcat (6/24/2008)
Besides the INDEX part,
(convert(VARCHAR(6), CombinedTT.StartTime, 112)= '{?Period}')
---- this one takes longer in WHERE clause.....
Better move the CONVERT into your SELECT...UNION ALL....part
Hey I tried this but didnt help me much to boost.
June 24, 2008 at 2:05 pm
Doing a convert on a column guarantees there's no chance of an index being used as effectively as it could... you need to change this...
AND (convert(VARCHAR(6), TT.StartTime, 112)= '{?Period}')
... to this...
AND (TT.StartTime >= '{?Period}'
AND TT.StartTime < DATEADD(dd,1,'{?Period}'))
--Jeff Moden
Change is inevitable... Change for the better is not.
June 24, 2008 at 2:10 pm
You also have many columns being returned in the SELECT lists of the derived tables that aren't used anywhere else... remove them. Just return enough data in those derived tables that are actually going to be used.
--Jeff Moden
Change is inevitable... Change for the better is not.
June 24, 2008 at 2:56 pm
ALZDBA (6/24/2008)
did you try to split the "UNION ALL"So to rewrite the full query using the TT table
and then perform a union all using the full query with the ArchTT table
does that make sence to you ?
Something like this...
SELECT CardID, EmployeeName, StartTime, EndTime, Autolunch, Punch, PunchType, PunchClass, HomeDivision, HomeDivisionDescript,
HomeDepartment, HomeDeptDescript, Department, DepartmentDescript, JobNumber, JobNumberDescription, Level4, Level4Description,
Level5, Level5Description, StartRounded, EndRounded, RegT, OT, DT, TotalTime, Dollars, Quantity, SchedNo, ShiftNo, ShiftNoDescript,
PayRate, TotalPayDol, BillRate, TotalBillDol, TotalDol, PayType, PayTypeDescript, ExceptionType, OTDescription, Notes, Counter, Status,
PayPeriodCode, PayPeriodDesc, LastUpdated, OtherID, Paid, AccrueToOT, TimeType, SatPremAmt, SunPremAmt, RegTComp, OTComp,
Premium1, ParentRec, Protect, DTComp, StartLocationNo, StartLocationType, StartLocationName, EndLocationNo, EndLocationType,
EndLocationName, ShiftGroupDesignator
FROM dbo.TT as TT
INNER JOIN
dbo.EmployeeT ON TT.CardID = dbo.EmployeeT.CardID INNER JOIN
dbo.PayPeriodT ON dbo.EmployeeT.PayPeriod = dbo.PayPeriodT.PayPeriodCode
WHERE (TT.TimeType IN ('1', '2', '4'))
AND (convert(VARCHAR(6), TT.StartTime, 112)= '{?Period}')
AND (TT.DepartmentDescript Like '{?ProjectName}')
UNION ALL
SELECT CardID, EmployeeName, StartTime, EndTime, Autolunch, Punch, PunchType, PunchClass, HomeDivision, HomeDivisionDescript,
HomeDepartment, HomeDeptDescript, Department, DepartmentDescript, JobNumber, JobNumberDescription, Level4, Level4Description,
Level5, Level5Description, StartRounded, EndRounded, RegT, OT, DT, TotalTime, Dollars, Quantity, SchedNo, ShiftNo, ShiftNoDescript,
PayRate, TotalPayDol, BillRate, TotalBillDol, TotalDol, PayType, PayTypeDescript, ExceptionType, OTDescription, Notes, Counter, Status,
PayPeriodCode, PayPeriodDesc, LastUpdated, OtherID, Paid, AccrueToOT, TimeType, SatPremAmt, SunPremAmt, RegTComp, OTComp,
Premium1, ParentRec, Protect, DTComp, StartLocationNo, StartLocationType, StartLocationName, EndLocationNo, EndLocationType,
EndLocationName, ShiftGroupDesignator
FROM dbo.ArchTT as ArchTT
INNER JOIN
dbo.EmployeeT ON ArchTT .CardID = dbo.EmployeeT.CardID INNER JOIN
dbo.PayPeriodT ON dbo.EmployeeT.PayPeriod = dbo.PayPeriodT.PayPeriodCode
WHERE (ArchTT.TimeType IN ('1', '2', '4'))
AND (convert(VARCHAR(6), ArchTT.StartTime, 112)= '{?Period}')
AND (ArchTT.DepartmentDescript Like '{?ProjectName}')
)
GROUP BY CombinedTT.Level4Description,CombinedTT.DepartmentDescript, CombinedTT.EmployeeName, CombinedTT.PunchType, CombinedTT.StartTime
HAVING (NOT (CombinedTT.PunchType IN ('S', 'V', 'AB'))
Hey may be this way i can tune my query but how could i do a group by on all my sleect statements if i split.
June 25, 2008 at 12:41 am
Here's a partially cleaned up exec plan if anyone wants to take a look.
Is the exec plan correct in estimating that only 2 rows are returned?
I asee 2 immediate problems. You have no clustered index on either the TT or the ArchTT tables,
just a nonclustered primary key on each.
As a result, you're getting an index scan and a very expensive bookmark lookup to the heap.
Is there a reason there is no clustered index?
First, fix the startdate and excess returned columns like Jeff suggested, then consider adding an index to support the query.
As a quick suggestion -
ArchTT: DepartmentDescript, StartTime, TimeType, PunchType
TT: DepartmentDescript, StartTime, TimeType, PunchType
No promices. It may help
Gail Shaw
Microsoft Certified Master: SQL Server, MVP, M.Sc (Comp Sci)
SQL In The Wild: Discussions on DB performance with occasional diversions into recoverability
June 25, 2008 at 5:41 am
Mike Levan (6/24/2008)
Hey may be this way i can tune my query but how could i do a group by on all my sleect statements if i split.
just as easy...
the point is to restrict the unioned rows to the minimum, and being able to optimize the indivituale parts.
btw only select the columns you're actualy going to use, because that may result in index only operations (at least for a part of the query).
Replace the datetime column filter by a >= and < the date parameter !!
This way it may be able to use an index on the datetime column !!
SELECT CombinedTT.Level4Description
, CombinedTT.EmployeeName
, CombinedTT.PunchType
, CombinedTT.DepartmentDescript
, SUM(( CASE WHEN TimeType = 1 THEN RegT / 60 ELSE 0 END )) AS RegT
, SUM(( CASE WHEN TimeType = 1 THEN OT / 60 ELSE 0 END )) AS OT
, SUM(( CASE WHEN TimeType = 1 THEN DT / 60 ELSE 0 END )) AS DT
, SUM(( CASE WHEN TimeType = 2 AND PunchType <> 'V' THEN TotalTime / 60 ELSE 0 END )) AS PTO
, SUM(( CASE WHEN TimeType = 2 AND PunchType <> 'V' THEN totaltime ELSE 0 END )
+ ( CASE WHEN TimeType = 1 THEN RegT ELSE 0 END )) AS RegTotal
, SUM(( CASE WHEN ( PunchType = 'LE' )
OR ( PunchType = 'LC' ) THEN TotalTime / 60
ELSE ( CASE WHEN TimeType <> 4 THEN AutoLunch / 60
ELSE 0
END )
END )) AS AutoLunch
, SUM(( CASE WHEN ( ( (TimeType = 1) )
AND ( ( PunchType <> 'LE' )
AND ( PunchType <> 'LC' )
)
OR ( TimeType = 2
AND PunchType <> 'V'
)
) THEN TotalTime / 60
ELSE 0
END )) AS TotalTime
, SUM(( CASE WHEN ( (TimeType = 1) )
AND ( ( PunchType <> 'LE' )
AND ( PunchType <> 'LC' )
) THEN TotalTime / 60
ELSE 0
END )) AS WorkedTime
, SUM(( ( ( CASE WHEN TimeType = 2
AND PunchType <> 'V' THEN totaltime
ELSE 0
END ) + ( CASE WHEN TimeType = 1 THEN RegT
ELSE 0
END ) ) + ( CASE WHEN TimeType = 1 THEN OT
ELSE 0
END ) * 1.5 )
+ ( CASE WHEN TimeType = 1 THEN DT
ELSE 0
END ) * 2) AS RTE
, SUM(CombinedTT.TotalPayDol) AS TotalPay
, SUM(CombinedTT.TotalBillDol) AS TotallBill
, convert(VARCHAR(6), CombinedTT.StartTime, 112) as Period
FROM ( SELECT
Level4Description
, EmployeeName
, PunchType
, DepartmentDescript
, TimeType
, PunchType
, RegT
, OT
, DT
, TotalPayDol
, TotalBillDol
, StartTime
FROM dbo.TT
INNER JOIN dbo.EmployeeT
ON CombinedTT.CardID = dbo.EmployeeT.CardID
INNER JOIN dbo.PayPeriodT
ON dbo.EmployeeT.PayPeriod = dbo.PayPeriodT.PayPeriodCode
WHERE ( TT.TimeType IN ( '1', '2', '4' ) )
AND ( convert(VARCHAR(6), TT.StartTime, 112) = '{?Period}' )
AND ( TT.DepartmentDescript Like '{?ProjectName}' )
UNION ALL
SELECT
Level4Description
, EmployeeName
, PunchType
, DepartmentDescript
, TimeType
, PunchType
, RegT
, OT
, DT
, TotalPayDol
, TotalBillDol
, StartTime
FROM dbo.ArchTT
INNER JOIN dbo.EmployeeT
ON CombinedTT.CardID = dbo.EmployeeT.CardID
INNER JOIN dbo.PayPeriodT
ON dbo.EmployeeT.PayPeriod = dbo.PayPeriodT.PayPeriodCode
WHERE ( ArchTT.TimeType IN ( '1', '2', '4' ) )
AND ( convert(VARCHAR(6), ArchTT.StartTime, 112) = '{?Period}' )
AND ( ArchTT.DepartmentDescript Like '{?ProjectName}' )
) CombinedTT
GROUP BY CombinedTT.Level4Description
, CombinedTT.DepartmentDescript
, CombinedTT.EmployeeName
, CombinedTT.PunchType
, CombinedTT.StartTime
HAVING ( NOT ( CombinedTT.PunchType IN ( 'S', 'V', 'AB' ) )
)
ORDER BY CombinedTT.DepartmentDescript
Johan
Learn to play, play to learn !
Dont drive faster than your guardian angel can fly ...
but keeping both feet on the ground wont get you anywhere :w00t:
- How to post Performance Problems
- How to post data/code to get the best help[/url]
- How to prevent a sore throat after hours of presenting ppt
press F1 for solution, press shift+F1 for urgent solution 😀
Need a bit of Powershell? How about this
Who am I ? Sometimes this is me but most of the time this is me
July 2, 2008 at 5:49 pm
I got this to run in 5sec but when i hook this up to a crystal report it takes 4 min to run for the first time, 5+min in the second time consequtively.
what might be the reason? what is that I can do from DB side to boost the performace of reports.
Guys Pls do check the EXEcution PLan(EP1) I have attahced for the Proc am running.
thanks
July 4, 2008 at 12:59 am
Regarding the first insert:
INSERT INTO #temp2
SELECT dbo.PJACCT.acct_group_cd
, dbo.PJACCT.acct
, SUM(dbo.PJTRAN.amount) AS SumAmt
, dbo.PJTRAN.fiscalno
, LTRIM(dbo.PJTRAN.employee + dbo.PJTRAN.vendor_num) AS Vendor_Emp
, dbo.PJTRAN.project
, LEFT(dbo.PJTRAN.fiscalno, 4) AS FiscalYr
, dbo.PJTRAN.tr_comment
, LTRIM(dbo.Vendor.Name + dbo.Employee.Name) AS C_Name
, ( CASE WHEN dbo.PJACCT.acct_group_cd = 'BU'
OR dbo.PJACCT.acct_group_cd = 'OL'
OR dbo.PJACCT.acct_group_cd = 'IL'
THEN 'LAB'
WHEN dbo.PJACCT.acct_group_cd = 'SU'
OR dbo.PJACCT.acct_group_cd = 'EQ'
OR dbo.PJACCT.acct_group_cd = 'AS'
THEN 'SUP'
WHEN dbo.PJACCT.acct_group_cd = 'GO' THEN 'TGO'
WHEN dbo.PJACCT.acct_group_cd = 'RV' THEN 'REV'
WHEN dbo.PJACCT.acct_group_cd = 'RE' THEN 'REH'
WHEN dbo.PJACCT.acct_group_cd = 'CO' THEN 'COH'
END ) AS Category
, dbo.PJPROJ.contract
, dbo.PJTRAN.trans_date
, dbo.Employee.EmpId
, dbo.Employee.Name AS EName
, dbo.Vendor.Name AS VName
FROM dbo.PJTRAN
INNER JOIN dbo.PJACCT
ON dbo.PJTRAN.acct = dbo.PJACCT.acct
LEFT OUTER JOIN dbo.Employee
ON dbo.PJTRAN.employee = dbo.Employee.EmpId
LEFT OUTER JOIN dbo.PJPROJ
ON dbo.PJTRAN.project = dbo.PJPROJ.project
LEFT OUTER JOIN dbo.Vendor
ON dbo.PJTRAN.vendor_num = dbo.Vendor.VendId
GROUP BY dbo.PJACCT.acct_group_cd
, dbo.PJTRAN.project
, dbo.PJTRAN.trans_date
, dbo.PJTRAN.tr_comment
, dbo.PJTRAN.fiscalno
, dbo.PJACCT.acct
, dbo.PJTRAN.employee
, dbo.PJTRAN.vendor_num
, dbo.Vendor.Name
, dbo.PJPROJ.contract
, dbo.Employee.EmpId
, dbo.Employee.Name
HAVING ( dbo.PJTRAN.fiscalno = @Period )
AND ( dbo.PJTRAN.project = @ProjectName )
Why are you using a "having" for this ?? Use a regular where-clause for this filter !
You can create indexes on #-tmp tables:
Depending on the number of rows / volume of the tmp tables, this may speed up your queries
/* tobe performed after the insert (to avoid fragmentation) */
create index [x_#temp2] on #temp2(EmpID);
/* tobe performed after the insert (to avoid fragmentation) */
create index [x_#temp1] on #temp1(EmployeeID);
Johan
Learn to play, play to learn !
Dont drive faster than your guardian angel can fly ...
but keeping both feet on the ground wont get you anywhere :w00t:
- How to post Performance Problems
- How to post data/code to get the best help[/url]
- How to prevent a sore throat after hours of presenting ppt
press F1 for solution, press shift+F1 for urgent solution 😀
Need a bit of Powershell? How about this
Who am I ? Sometimes this is me but most of the time this is me
Viewing 15 posts - 1 through 14 (of 14 total)
You must be logged in to reply to this topic. Login to reply