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.

 All Forums
 SQL Server 2000 Forums
 Transact-SQL (2000)
 Stored Procedure response time

Author  Topic 

mk_garg20
Constraint Violating Yak Guru

343 Posts

Posted - 2004-07-13 : 21:44:23
Hi All,
I have following stored procedure.
which is getting data from different databases & tables.
Currently it is taking 8 minutes to return data.
What can i do to reduce response time.
Thanks
Manoj

CREATE PROCEDURE [dbo].[sp_Get_DynSalesAndBudgetFigures] (@StartDate AS VarChar(10), @EndDate AS VarChar(10))
AS

/*
Testing variables
DECLARE @StartDate AS VarChar(10)
DECLARE @EndDate AS VarChar(10)
*/
DECLARE @StartMonth AS VARCHAR(50)
DECLARE @EndMonth AS VARCHAR(50)
DECLARE @StartYear AS VARCHAR(50)
DECLARE @EndYear AS VARCHAR(50)
DECLARE @FinYear AS VARCHAR(4)
DECLARE @SDate AS VARCHAR(50)
DECLARE @EDate AS VARCHAR(50)

DECLARE @QueryString AS VARCHAR(8000)
DECLARE @ConditionString AS VARCHAR(1000)
/*
Testing variables
SET @StartDate = '01/08/2003'
SET @EndDate = '31/08/2003'
*/
SET @SDate = 'CONVERT(DATETIME, ''' + @StartDate + ''', 103)'

IF LEN(LTRIM(RTRIM(@EndDate))) = 0
SET @EDate = 'CONVERT(DATETIME, ''' + @StartDate + ''', 103) + 6 '
ELSE
SET @EDate = 'CONVERT(DATETIME, ''' + @EndDate+ ''', 103)'

SET @StartMonth = 'MONTH(CONVERT(DATETIME, ''' + @StartDate + ''', 103))'
SET @EndMonth = 'MONTH(CONVERT(DATETIME, ''' + @EndDate+ ''', 103))'
SET @StartYear = 'YEAR(CONVERT(DATETIME, ''' + @StartDate + ''', 103))'
SET @EndYear = 'YEAR(CONVERT(DATETIME, ''' + @EndDate+ ''', 103))'

-- Calculate the Financial year
IF YEAR(CONVERT(DATETIME, @StartDate, 103)) = YEAR(CONVERT(DATETIME, @EndDate, 103))
BEGIN

SET @ConditionString = 'WHERE db..DynBudget.Month >= ' + @StartMonth + ' AND
db..DynBudget.Month <= ' + @EndMonth

IF MONTH(CONVERT(DATETIME, @StartDate, 103)) < 7
SET @FinYear = YEAR(CONVERT(DATETIME, @StartDate, 103))
ELSE
SET @FinYear = YEAR(CONVERT(DATETIME, @StartDate, 103)) + 1
END
ELSE
BEGIN

SET @ConditionString = 'WHERE ((db..DynBudget.Month >= ' + @StartMonth + ') AND (db..DynBudget.Year = ' + @StartYear + '))
OR ((db..DynBudget.Month <= ' + @EndMonth + ') AND (db..DynBudget.Year = ' + @EndYear + '))'

IF MONTH(CONVERT(DATETIME, @EndDate, 103)) < 7
SET @FinYear = YEAR(CONVERT(DATETIME, @EndDate, 103))
END

SET @QueryString = 'SELECT ClientID, DeptID, SUM(Amount) AS Amount INTO #Bdgt
FROM db..DynBudget ' + RTRIM(@ConditionString) + ' AND db..DynBudget.FinYear = ' + @FinYear + ' GROUP BY ClientID, DeptID
SELECT * INTO #GL FROM CIMEL04.CDSYD.DBO.GL20000 GL20000
WHERE GL20000.trxdate < (' + @EDate + ' + 1) AND GL20000.trxdate >= ' + @SDate + '
ORDER BY GL20000.ORMSTRID
SELECT DISTINCT RM00101.Custnmbr AS Client, RM00101.CustName AS ClientName
INTO #GLCL FROM CIMEL04.CDSYD.DBO.RM00101 RM00101 ORDER BY RM00101.Custnmbr
SELECT ClientID, SUM(Amount) AS Amount
INTO #BdgLaser FROM #Bdgt WHERE (#Bdgt.DeptID = ''14'' OR #Bdgt.DeptID = ''09'') GROUP BY ClientID

SELECT * INTO #GL00100 FROM CIMEL04.CDSYD.DBO.GL00100 WHERE LTRIM(Actnumbr_2) in (''12'', ''14'', ''03'', ''04'', ''07'', ''15'', ''17'', ''19'', ''11'') and (CAST(RTRIM(LTRIM(actnumbr_3)) as integer) >= 100) and (cast(rtrim(ltrim(actnumbr_3)) as Integer) <= 199)

SELECT Client AS ORMSTRID, SUM(Crdtamnt)AS LaserCredit, SUM(debitamt) AS LaserDebit, #BdgLaser.Amount AS BudgtdLaserAmt
INTO #LASER FROM #GLCL FULL JOIN #GL ON #GL.ORMSTRID = #GLCL.Client LEFT JOIN #BdgLaser ON #GLCL.Client = #BdgLaser.ClientID
WHERE #GL.actindx IN (SELECT actindx FROM #GL00100 WHERE LTRIM(Actnumbr_2) = ''14'' and (CAST(RTRIM(LTRIM(actnumbr_3)) as integer) >= 100) and (cast(rtrim(ltrim(actnumbr_3)) as Integer) <= 199))
GROUP BY ALL #GLCL.Client, #BdgLaser.Amount

SELECT Client AS ORMSTRID, SUM(Crdtamnt)AS MailCredit, SUM(debitamt) AS MailDebit, #Bdgt.Amount AS BudgtdMailAmt
INTO #MAIL FROM #GLCL FULL JOIN #GL ON #GL.ORMSTRID = #GLCL.Client LEFT JOIN #Bdgt ON #GLCL.Client = #Bdgt.ClientID AND #Bdgt.DeptID = ''15''
WHERE #GL.actindx IN (SELECT actindx FROM #GL00100 WHERE LTRIM(Actnumbr_2) = ''15'' and (CAST(RTRIM(LTRIM(actnumbr_3)) as integer) >= 100) and (cast(rtrim(ltrim(actnumbr_3)) as Integer) <= 199))
GROUP BY ALL #GLCL.Client, #Bdgt.Amount

SELECT Client AS ORMSTRID, SUM(Crdtamnt)AS MaterialCredit, SUM(debitamt) AS MaterialDebit, #Bdgt.Amount AS BudgtdMaterialAmt
INTO #MATERIAL FROM #GLCL FULL JOIN #GL ON #GL.ORMSTRID = #GLCL.Client LEFT JOIN #Bdgt ON #GLCL.Client = #Bdgt.ClientID AND #Bdgt.DeptID = ''17''
WHERE #GL.actindx IN (SELECT actindx FROM #GL00100 WHERE LTRIM(Actnumbr_2) = ''17'' and (CAST(RTRIM(LTRIM(actnumbr_3)) as integer) >= 100) and (cast(rtrim(ltrim(actnumbr_3)) as Integer) <= 199))
GROUP BY ALL #GLCL.Client, #Bdgt.Amount

SELECT Client AS ORMSTRID, SUM(Crdtamnt)AS ProgramCredit, SUM(debitamt) AS ProgramDebit, #Bdgt.Amount AS BudgtdProgramAmt
INTO #PROGRAM FROM #GLCL FULL JOIN #GL ON #GL.ORMSTRID = #GLCL.Client LEFT JOIN #Bdgt ON #GLCL.Client = #Bdgt.ClientID AND #Bdgt.DeptID = ''12''
WHERE #GL.actindx IN (SELECT actindx FROM #GL00100 WHERE LTRIM(Actnumbr_2) = ''12'' and (CAST(RTRIM(LTRIM(actnumbr_3)) as integer) >= 100) and (cast(rtrim(ltrim(actnumbr_3)) as Integer) <= 199))
GROUP BY ALL #GLCL.Client, #Bdgt.Amount

SELECT Client AS ORMSTRID, SUM(Crdtamnt)AS EBCredit, SUM(debitamt) AS EBDebit, #Bdgt.Amount AS BudgtdEBAmt
INTO #EBIZ FROM #GLCL FULL JOIN #GL ON #GL.ORMSTRID = #GLCL.Client LEFT JOIN #Bdgt ON #GLCL.Client = #Bdgt.ClientID AND #Bdgt.DeptID = ''19''
WHERE #GL.actindx IN (SELECT actindx FROM #GL00100 WHERE LTRIM(Actnumbr_2) = ''19'' and (CAST(RTRIM(LTRIM(actnumbr_3)) as integer) >= 100) and (cast(rtrim(ltrim(actnumbr_3)) as Integer) <= 199))
GROUP BY ALL #GLCL.Client, #Bdgt.Amount

SELECT Client AS ORMSTRID, SUM(Crdtamnt)AS DesignCredit, SUM(debitamt) AS DesignDebit, #Bdgt.Amount AS BudgtdDesignAmt
INTO #DESIGN FROM #GLCL FULL JOIN #GL ON #GL.ORMSTRID = #GLCL.Client LEFT JOIN #Bdgt ON #GLCL.Client = #Bdgt.ClientID AND #Bdgt.DeptID = ''11''
WHERE #GL.actindx IN (SELECT actindx FROM #GL00100 WHERE LTRIM(Actnumbr_2) = ''11'' and (CAST(RTRIM(LTRIM(actnumbr_3)) as integer) >= 100) and (cast(rtrim(ltrim(actnumbr_3)) as Integer) <= 199))
GROUP BY ALL #GLCL.Client, #Bdgt.Amount

SELECT Client AS ORMSTRID, SUM(Crdtamnt)AS LodgementCredit, SUM(debitamt) AS LodgementDebit, #Bdgt.Amount AS BudgtdLodgementAmt
INTO #LODGEMENT FROM #GLCL FULL JOIN #GL ON #GL.ORMSTRID = #GLCL.Client LEFT JOIN #Bdgt ON #GLCL.Client = #Bdgt.ClientID AND #Bdgt.DeptID = ''08''
WHERE #GL.actindx IN (SELECT actindx FROM #GL00100 WHERE LTRIM(Actnumbr_2) = ''04'' and (CAST(RTRIM(LTRIM(actnumbr_3)) as integer) = 102))
GROUP BY ALL #GLCL.Client, #Bdgt.Amount

SELECT Client AS ORMSTRID, SUM(Crdtamnt)AS PostageCredit, SUM(debitamt) AS PostageDebit, #Bdgt.Amount AS BudgtdPostageAmt
INTO #POSTAGE FROM #GLCL FULL JOIN #GL ON #GL.ORMSTRID = #GLCL.Client LEFT JOIN #Bdgt ON #GLCL.Client = #Bdgt.ClientID AND #Bdgt.DeptID = ''04''
WHERE #GL.actindx IN (SELECT actindx FROM #GL00100 WHERE LTRIM(Actnumbr_2) = ''04'' and (CAST(RTRIM(LTRIM(actnumbr_3)) as integer) IN (180, 181)))
GROUP BY ALL #GLCL.Client, #Bdgt.Amount

SELECT Client AS ORMSTRID, SUM(Crdtamnt)AS FreightCredit, SUM(debitamt) AS FreightDebit, #Bdgt.Amount AS BudgtdFreightAmt
INTO #FREIGHT FROM #GLCL FULL JOIN #GL ON #GL.ORMSTRID = #GLCL.Client LEFT JOIN #Bdgt ON #GLCL.Client = #Bdgt.ClientID AND #Bdgt.DeptID = ''03''
WHERE #GL.actindx IN (SELECT actindx FROM #GL00100 WHERE LTRIM(Actnumbr_2) = ''03'' and (CAST(RTRIM(LTRIM(actnumbr_3)) as integer) >= 100) and (cast(rtrim(ltrim(actnumbr_3)) as Integer) <= 199))
GROUP BY ALL #GLCL.Client, #Bdgt.Amount

SELECT #GLCL.Client, #GLCL.ClientName,
ISNULL((#LASER.LaserCredit - #LASER.LaserDebit),0) AS Laser, ISNULL(#LASER.BudgtdLaserAmt, 0) AS BudgtdLaser,
ISNULL((#MAIL.MailCredit - #MAIL.MailDebit),0) AS Mail, ISNULL(#MAIL.BudgtdMailAmt, 0) AS BudgtdMail,
ISNULL((#MATERIAL.MaterialCredit - #MATERIAL.MaterialDebit),0) AS Material, ISNULL(#MATERIAL.BudgtdMaterialAmt, 0) AS BudgtdMaterial,
ISNULL((#PROGRAM.ProgramCredit - #PROGRAM.ProgramDebit),0) AS Program, ISNULL(#PROGRAM.BudgtdProgramAmt, 0) AS BudgtdProgram,
ISNULL((#EBIZ.EBCredit - #EBIZ.EBDebit),0) AS EBiz, ISNULL(#EBIZ.BudgtdEBAmt, 0) AS BudgtdEBiz,
ISNULL((#DESIGN.DesignCredit - #DESIGN.DesignDebit),0) AS Design, ISNULL(#DESIGN.BudgtdDesignAmt, 0) AS BudgtdDesign,
ISNULL((#LODGEMENT.LodgementCredit - #LODGEMENT.LodgementDebit),0) AS Lodgement, ISNULL(#LODGEMENT.BudgtdLodgementAmt, 0) AS BudgtdLodgement,
ISNULL((#POSTAGE.PostageCredit - #POSTAGE.PostageDebit),0) AS Postage, ISNULL(#POSTAGE.BudgtdPostageAmt, 0) AS BudgtdPostage,
ISNULL((#FREIGHT.FreightCredit - #FREIGHT.FreightDebit),0) AS Freight, ISNULL(#FREIGHT.BudgtdFreightAmt, 0) AS BudgtdFreight
INTO #FINAL FROM #GLCL FULL JOIN #LASER ON #GLCL.Client = #LASER.ORMSTRID FULL JOIN #MAIL ON #GLCL.Client = #MAIL.ORMSTRID
FULL JOIN #MATERIAL ON #GLCL.Client = #MATERIAL.ORMSTRID FULL JOIN #PROGRAM ON #GLCL.Client = #PROGRAM.ORMSTRID
FULL JOIN #EBIZ ON #GLCL.Client = #EBIZ.ORMSTRID FULL JOIN #DESIGN ON #GLCL.Client = #DESIGN.ORMSTRID
FULL JOIN #LODGEMENT ON #GLCL.Client = #LODGEMENT.ORMSTRID FULL JOIN #POSTAGE ON #GLCL.Client = #POSTAGE.ORMSTRID
FULL JOIN #FREIGHT ON #GLCL.Client = #FREIGHT.ORMSTRID ORDER BY #GLCL.Client

SELECT Client, ClientName, SUM(Laser) as Laser, SUM(BudgtdLaser) AS BudgtdLaser, SUM(Mail) AS Mail, SUM(BudgtdMail) AS BudgtdMail, SUM(Material) AS Material, SUM(BudgtdMaterial) AS BudgtdMaterial,
SUM(Program) AS Program, SUM(BudgtdProgram) AS BudgtdProgram, SUM(EBiz) AS EBiz, SUM(BudgtdEBiz) AS BudgtdEBiz, SUM(Design) AS Design, SUM(BudgtdDesign) AS BudgtdDesign, SUM(Lodgement) AS Lodgement, SUM(BudgtdLodgement) AS BudgtdLodgement,
SUM(Postage) AS Postage, SUM(BudgtdPostage) AS BudgtdPostage, SUM(Freight) AS Freight, SUM(BudgtdFreight) AS BudgtdFreight
FROM #FINAL GROUP BY Client, ClientName ORDER BY Client
'
EXEC( @QueryString )






Kristen
Test

22859 Posts

Posted - 2004-07-14 : 03:10:31
Blimey!, there's loads of stuff I think I can suggest that will be useful. The others will be along in a minute with their critical review hats on!

But seeing as how you asked:

DECLARE @StartMonth AS VARCHAR(50)
DECLARE @EndMonth AS VARCHAR(50)

Is the data this is being compared against CHAR or INT? I suspect INT, thus better these working variables are the same type too (saves a conversion)


SELECT * INTO #GL FROM CIMEL04.CDSYD.DBO.GL20000 GL20000

Don't use SELECT *, use a column list (and only use the columns that you ACTUALLY need)

Don't use "INTO #GL" - SQL has to work out what you mean each time, and cannot therefore store a query plan for the SProc, instead use:

CREATE TABLE #GL
(
...
)
INSERT INTO #GL
SELECT a,b,c FROM CIMEL04.CDSYD.DBO.GL20000 GL20000

Also, once you have changed to using CREATE TABLE #TEMP style then you can put a PRIMARY KEY and, if necessary, some INDEXES on the temporary table. In my experience this will make a HUGE difference (I would not be surprised to hear that this alone makes TWO orders of magnitude differences (i.e. cuts run time by 99%) assuming you have a large number of rows in the temporary tables.


SELECT *
INTO #GL00100
FROM CIMEL04.CDSYD.DBO.GL00100
WHERE LTRIM(Actnumbr_2) in (''12'', ''14'', ''03'', ''04'', ''07'', ''15'', ''17'', ''19'', ''11'')
and (CAST(RTRIM(LTRIM(actnumbr_3)) as integer) >= 100)
and (cast(rtrim(ltrim(actnumbr_3)) as Integer) <= 199)

The CAST/TRIM stuff on the column in CIMEL04.CDSYD.DBO.GL00100 will prevent SQL using any indexes. The data needs storing in columns, in that table, in the appropriate form - not just some "rubbish" with gash spaces etc.

If its a STAGING table of imported, "dirty", data clean it up with some UPDATE statements first.


WHERE #GL.actindx IN (SELECT actindx FROM #GL00100 WHERE LTRIM(Actnumbr_2) = ''14''

Don't use IN (SELECT ... - this is [usually] much slower than a JOIN


Finally the fact that this is all dynamic SQL will not help at all! Moving the bits that don't need to be dynamic (the bits that populate some TMP tables maybe, or the bits that work on those temp tables once populated) to be part of the SProc will mean that their query plan will be cached, and run faster.

Actually, I'm not sure you need any dynamic SQL at all, but its a fair bit of code to read through to be sure. If you can remove the dynamic stuff that will make a huge difference.

Alternatively, you could "parameterise" the dynamic SQL and use sp_executeSQL instead. However, I can oly really see a benefit in this if you reuse this SProc often. If its a once-a-month jobbie then don't bother.

Kristen
Go to Top of Page

mk_garg20
Constraint Violating Yak Guru

343 Posts

Posted - 2004-07-14 : 23:39:00
Kristen,
Are you suggesting to create table(CREATE TABLE #TEMP ) outside the stored procedure so that it will not be created each time stored procedure is called.
Thanks
Manoj
Go to Top of Page

Kristen
Test

22859 Posts

Posted - 2004-07-15 : 09:44:14
Nope, its OK to create it within the SProc - you just need to create it using CREATE TABLE rather than SELECT * INTO #TEMP ... (and make sure you put a PRIMARY KEY, and possibly an index, on it)

Kristen
Go to Top of Page

aiken
Aged Yak Warrior

525 Posts

Posted - 2004-07-15 : 12:19:30
Alternatively, if you don't need indexes on a particular temp table, consider using table variables instead (you can really only do PK and unique indexes on table variables). That can also dramatically boost performance, since it's all in memory and doesn't touch tempdb.

Cheers
-b
Go to Top of Page

mk_garg20
Constraint Violating Yak Guru

343 Posts

Posted - 2004-07-15 : 18:24:34
Thanks Kristen& Aiken,
I am using SQL server 7.0. SO can't use table variables.

Manoj
Go to Top of Page

Kristen
Test

22859 Posts

Posted - 2004-07-16 : 01:40:20
I don't udnerstand why you are using dynamic SQL in the procedure - it doesn't seem to be doing anything "dynamic".

I presume you are aware that the dynamic SQL is within a few bytes of the 8,000 character limit?

Kristen
Go to Top of Page

mk_garg20
Constraint Violating Yak Guru

343 Posts

Posted - 2004-07-16 : 01:55:34
Kristen,
This procedure is used by Crystal Report.
I changes select * into #GL to create table #GL and theb insert into #GL.

But it is not giving better response.
This Procedure was wriiten by someone else.

Can you please tell me bit more about 8000 limit. if i don't use Dynamic SQL. Can i achieve same result. in this stored Procedure.

Thanks
Manoj

Go to Top of Page

Kristen
Test

22859 Posts

Posted - 2004-07-16 : 05:41:52
Did you put a Primary Key on #GL? You need to do all the other temporary tables too

I checked the size of the
SET @QueryString = 'SELECT ...
statement and it is close to 8000 characters. If you extend this much more you will be over that limit - just so long as you are aware.

I can't see why you can't do:

CREATE PROCEDURE [dbo].[sp_Get_DynSalesAndBudgetFigures]
(
@StartDate AS VarChar(10),
@EndDate AS VarChar(10)
)
AS

/*
Testing variables
DECLARE @StartDate AS VarChar(10)
DECLARE @EndDate AS VarChar(10)
*/
DECLARE @StartMonth AS VARCHAR(50)
DECLARE @EndMonth AS VARCHAR(50)
DECLARE @StartYear AS VARCHAR(50)
DECLARE @EndYear AS VARCHAR(50)
DECLARE @FinYear AS VARCHAR(4)
DECLARE @SDate AS VARCHAR(50)
DECLARE @EDate AS VARCHAR(50)

-- DECLARE @QueryString AS VARCHAR(8000)
-- DECLARE @ConditionString AS VARCHAR(1000)
/*
Testing variables
SET @StartDate = '01/08/2003'
SET @EndDate = '31/08/2003'
*/
SET @SDate = CONVERT(DATETIME, @StartDate, 103)

IF LEN(LTRIM(RTRIM(@EndDate))) = 0
SET @EDate = CONVERT(DATETIME, @StartDate, 103) + 6
ELSE
SET @EDate = CONVERT(DATETIME, @EndDate, 103)

SET @StartMonth = MONTH(CONVERT(DATETIME, @StartDate, 103))
SET @EndMonth = MONTH(CONVERT(DATETIME, @EndDate, 103))
SET @StartYear = YEAR(CONVERT(DATETIME, @StartDate, 103))
SET @EndYear = YEAR(CONVERT(DATETIME, @EndDate, 103))

-- Calculate the Financial year
IF YEAR(CONVERT(DATETIME, @StartDate, 103)) = YEAR(CONVERT(DATETIME, @EndDate, 103))
BEGIN

-- SET @ConditionString = 'WHERE db..DynBudget.Month >= ' + @StartMonth + ' AND
-- db..DynBudget.Month <= ' + @EndMonth


IF MONTH(CONVERT(DATETIME, @StartDate, 103)) < 7
SET @FinYear = YEAR(CONVERT(DATETIME, @StartDate, 103))
ELSE
SET @FinYear = YEAR(CONVERT(DATETIME, @StartDate, 103)) + 1
END
ELSE
BEGIN

-- SET @ConditionString = 'WHERE ((db..DynBudget.Month >= ' + @StartMonth + ')
-- AND (db..DynBudget.Year = ' + @StartYear + '))
-- OR ((db..DynBudget.Month <= ' + @EndMonth + ') AND (db..DynBudget.Year = ' + @EndYear + '))'


IF MONTH(CONVERT(DATETIME, @EndDate, 103)) < 7
SET @FinYear = YEAR(CONVERT(DATETIME, @EndDate, 103))
END

-- SET @QueryString =
SELECT ClientID, DeptID, SUM(Amount) AS Amount INTO #Bdgt
FROM db..DynBudget

WHERE ((db..DynBudget.Month >= @StartMonth ) AND (db..DynBudget.Year = @StartYear ))
OR ((db..DynBudget.Month <= @EndMonth ) AND (db..DynBudget.Year = @EndYear ))

AND db..DynBudget.FinYear = @FinYear

GROUP BY ClientID, DeptID

CREATE TABLE #GL
(
... Column Definitions here ...
... With PK definition ...
)
INSERT INTO #GL

SELECT * ... column list here ...
-- INTO #GL
FROM CIMEL04.CDSYD.DBO.GL20000 GL20000

WHERE GL20000.trxdate < ( @EDate + 1)
AND GL20000.trxdate >= @SDate

ORDER BY GL20000.ORMSTRID


CREATE TABLE #GLCL
(
... Column Definitions here ...
... With PK definition ...
Client datatype NOT NULL PRIMARY KEY,
ClientName datatype
)
INSERT INTO #GLCL

SELECT DISTINCT
RM00101.Custnmbr AS Client,
RM00101.CustName AS ClientName
-- INTO #GLCL
FROM CIMEL04.CDSYD.DBO.RM00101 RM00101
ORDER BY RM00101.Custnmbr


CREATE TABLE #BdgLaser
(
... Column Definitions here ...
... With PK definition ...
ClientID datatype NOT NULL PRIMARY KEY,
Amount datatype
)
INSERT INTO #BdgLaser

SELECT ClientID,
SUM(Amount) AS Amount
-- INTO #BdgLaser
FROM #Bdgt
WHERE ( #Bdgt.DeptID = '14'
OR #Bdgt.DeptID = '09')
GROUP BY ClientID


CREATE TABLE #GL00100
(
... Column Definitions here ...
... With PK definition ...
... Make sure that Actnumbr_2 and Actnumbr_3 are stored as INT types ...
... and remove all the TRIM and CAST on these columns below ...
... Make sure Actnumbr_2 and Actnumbr_3 are indexed ...
)
INSERT INTO #GL00100

SELECT * ... column list here ...
-- INTO #GL00100
FROM CIMEL04.CDSYD.DBO.GL00100
-- TRIM here is bad for performance
WHERE LTRIM(Actnumbr_2) in ('12', '14', '03', '04', '07', '15', '17', '19', '11')
-- CAST/TRIM here is bad for performance
and (CAST(RTRIM(LTRIM(actnumbr_3)) as integer) >= 100)
-- CAST/TRIM here is bad for performance
and (cast(rtrim(ltrim(actnumbr_3)) as Integer) <= 199)


CREATE TABLE #LASER
(
... Column Definitions here ...
... With PK definition ...
ORMSTRID datatype NOT NULL PRIMARY KEY,
LaserCredit datatype,
LaserDebit datatype,
BudgtdLaserAmt datatype
)
INSERT INTO #LASER

SELECT Client AS ORMSTRID,
SUM(Crdtamnt)AS LaserCredit,
SUM(debitamt) AS LaserDebit,
#BdgLaser.Amount AS BudgtdLaserAmt
-- INTO #LASER
FROM #GLCL
-- FULL JOIN expensive, is it required?
FULL JOIN #GL
ON #GL.ORMSTRID = #GLCL.Client
LEFT JOIN #BdgLaser
ON #GLCL.Client = #BdgLaser.ClientID
-- IN very bad for performance here, use JOIN isntead (optimiser MAY be doing this anyway)
WHERE #GL.actindx IN
(
SELECT actindx
FROM #GL00100
-- TRIM here is bad for performance
WHERE LTRIM(Actnumbr_2) = '14'
-- CAST/TRIM here is bad for performance
and (CAST(RTRIM(LTRIM(actnumbr_3)) as integer) >= 100)
-- CAST/TRIM here is bad for performance
and (cast(rtrim(ltrim(actnumbr_3)) as Integer) <= 199)
)
GROUP BY ALL #GLCL.Client, #BdgLaser.Amount


CREATE TABLE #MAIL
(
... Column Definitions here ...
... With PK definition ...
ORMSTRID datatype NOT NULL PRIMARY KEY,
MailCredit datatype,
MailDebit datatype,
BudgtdMailAmt datatype
)
INSERT INTO #MAIL

SELECT Client AS ORMSTRID,
SUM(Crdtamnt)AS MailCredit,
SUM(debitamt) AS MailDebit,
#Bdgt.Amount AS BudgtdMailAmt
-- INTO #MAIL
FROM #GLCL
-- FULL JOIN expensive, is it required?
FULL JOIN #GL
ON #GL.ORMSTRID = #GLCL.Client
LEFT JOIN #Bdgt
ON #GLCL.Client = #Bdgt.ClientID
AND #Bdgt.DeptID = '15'
-- IN very bad for performance here, use JOIN isntead (optimiser MAY be doing this anyway)
WHERE #GL.actindx IN
(
SELECT actindx
FROM #GL00100
-- TRIM here is bad for performance
WHERE LTRIM(Actnumbr_2) = '15'
-- CAST/TRIM here is bad for performance
and (CAST(RTRIM(LTRIM(actnumbr_3)) as integer) >= 100)
-- CAST/TRIM here is bad for performance
and (cast(rtrim(ltrim(actnumbr_3)) as Integer) <= 199)
)
GROUP BY ALL #GLCL.Client, #Bdgt.Amount


CREATE TABLE #MATERIAL
(
... Column Definitions here ...
... With PK definition ...
ORMSTRID datatype NOT NULL PRIMARY KEY,
MaterialCredit datatype,
MaterialDebit datatype,
BudgtdMaterialAmt datatype
)
INSERT INTO #MATERIAL

SELECT Client AS ORMSTRID,
SUM(Crdtamnt)AS MaterialCredit,
SUM(debitamt) AS MaterialDebit,
#Bdgt.Amount AS BudgtdMaterialAmt
FROM #GLCL
-- FULL JOIN expensive, is it required?
FULL JOIN #GL
ON #GL.ORMSTRID = #GLCL.Client
LEFT JOIN #Bdgt
ON #GLCL.Client = #Bdgt.ClientID
AND #Bdgt.DeptID = '17'
-- IN very bad for performance here, use JOIN isntead (optimiser MAY be doing this anyway)
WHERE #GL.actindx IN
(
SELECT actindx
FROM #GL00100
-- TRIM here is bad for performance
WHERE LTRIM(Actnumbr_2) = '17'
-- CAST/TRIM here is bad for performance
and (CAST(RTRIM(LTRIM(actnumbr_3)) as integer) >= 100)
-- CAST/TRIM here is bad for performance
and (cast(rtrim(ltrim(actnumbr_3)) as Integer) <= 199)
)
GROUP BY ALL #GLCL.Client, #Bdgt.Amount


CREATE TABLE #PROGRAM
(
... Column Definitions here ...
... With PK definition ...
ORMSTRID datatype NOT NULL PRIMARY KEY,
MaterialCredit datatype,
MaterialDebit datatype,
BudgtdMaterialAmt datatype
)
INSERT INTO #PROGRAM

SELECT Client AS ORMSTRID,
SUM(Crdtamnt)AS ProgramCredit,
SUM(debitamt) AS ProgramDebit,
#Bdgt.Amount AS BudgtdProgramAmt
FROM #GLCL
-- FULL JOIN expensive, is it required?
FULL JOIN #GL
ON #GL.ORMSTRID = #GLCL.Client
LEFT JOIN #Bdgt
ON #GLCL.Client = #Bdgt.ClientID
AND #Bdgt.DeptID = '12'
-- IN very bad for performance here, use JOIN isntead (optimiser MAY be doing this anyway)
WHERE #GL.actindx IN
(
SELECT actindx
FROM #GL00100
-- TRIM here is bad for performance
WHERE LTRIM(Actnumbr_2) = '12'
-- CAST/TRIM here is bad for performance
and (CAST(RTRIM(LTRIM(actnumbr_3)) as integer) >= 100)
-- CAST/TRIM here is bad for performance
and (cast(rtrim(ltrim(actnumbr_3)) as Integer) <= 199)
)
GROUP BY ALL #GLCL.Client, #Bdgt.Amount


CREATE TABLE #EBIZ
(
... Column Definitions here ...
... With PK definition ...
ORMSTRID datatype NOT NULL PRIMARY KEY,
EBCredit datatype,
EBDebit datatype,
BudgtdEBAmt datatype
)
INSERT INTO #EBIZ

SELECT Client AS ORMSTRID,
SUM(Crdtamnt)AS EBCredit,
SUM(debitamt) AS EBDebit,
#Bdgt.Amount AS BudgtdEBAmt
-- INTO #EBIZ
FROM #GLCL
FULLJOIN #GL
ON #GL.ORMSTRID = #GLCL.Client
LEFT JOIN #Bdgt
ON #GLCL.Client = #Bdgt.ClientID
AND #Bdgt.DeptID = '19'
WHERE #GL.actindx IN
(
SELECT actindx
FROM #GL00100
WHERE LTRIM(Actnumbr_2) = '19'
and (CAST(RTRIM(LTRIM(actnumbr_3)) as integer) >= 100)
and (cast(rtrim(ltrim(actnumbr_3)) as Integer) <= 199)
)
GROUP BY ALL #GLCL.Client, #Bdgt.Amount


CREATE TABLE #EBIZ
(
... Column Definitions here ...
... With PK definition ...
ORMSTRID datatype NOT NULL PRIMARY KEY,
DesignCredit datatype,
DesignDebit datatype,
BudgtdDesignAmt datatype
)
INSERT INTO #EBIZ

SELECT Client AS ORMSTRID,
SUM(Crdtamnt)AS DesignCredit,
SUM(debitamt) AS DesignDebit,
#Bdgt.Amount AS BudgtdDesignAmt
-- INTO #DESIGN
FROM #GLCL
FULL JOIN #GL
ON #GL.ORMSTRID = #GLCL.Client
LEFT JOIN #Bdgt
ON #GLCL.Client = #Bdgt.ClientID
AND #Bdgt.DeptID = '11'
WHERE #GL.actindx IN
(
SELECT actindx
FROM #GL00100
WHERE LTRIM(Actnumbr_2) = '11'
and (CAST(RTRIM(LTRIM(actnumbr_3)) as integer) >= 100)
and (cast(rtrim(ltrim(actnumbr_3)) as Integer) <= 199)
)
GROUP BY ALL #GLCL.Client, #Bdgt.Amount


CREATE TABLE #LODGEMENT
(
... Column Definitions here ...
... With PK definition ...
ORMSTRID datatype NOT NULL PRIMARY KEY,
DesignCredit datatype,
DesignDebit datatype,
BudgtdDesignAmt datatype
)
INSERT INTO #LODGEMENT

SELECT Client AS ORMSTRID,
SUM(Crdtamnt)AS LodgementCredit,
SUM(debitamt) AS LodgementDebit,
#Bdgt.Amount AS BudgtdLodgementAmt
-- INTO #LODGEMENT
FROM #GLCL
FULL JOIN #GL
ON #GL.ORMSTRID = #GLCL.Client
LEFT JOIN #Bdgt
ON #GLCL.Client = #Bdgt.ClientID
AND #Bdgt.DeptID = '08'
WHERE #GL.actindx IN
(
SELECT actindx
FROM #GL00100
WHERE LTRIM(Actnumbr_2) = '04'
and (CAST(RTRIM(LTRIM(actnumbr_3)) as integer) = 102))
GROUP BY ALL #GLCL.Client, #Bdgt.Amount


CREATE TABLE #POSTAGE
(
... Column Definitions here ...
... With PK definition ...
ORMSTRID datatype NOT NULL PRIMARY KEY,
PostageCredit datatype,
PostageDebit datatype,
BudgtdPostageAmt datatype
)
INSERT INTO #POSTAGE

SELECT Client AS ORMSTRID,
SUM(Crdtamnt)AS PostageCredit,
SUM(debitamt) AS PostageDebit,
#Bdgt.Amount AS BudgtdPostageAmt
-- INTO #POSTAGE
FROM #GLCL
FULL JOIN #GL
ON #GL.ORMSTRID = #GLCL.Client
LEFT JOIN #Bdgt
ON #GLCL.Client = #Bdgt.ClientID
AND #Bdgt.DeptID = '04'
WHERE #GL.actindx IN
(
SELECT actindx
FROM #GL00100
WHERE LTRIM(Actnumbr_2) = '04'
and (CAST(RTRIM(LTRIM(actnumbr_3)) as integer) IN (180, 181)))
GROUP BY ALL #GLCL.Client, #Bdgt.Amount


CREATE TABLE #FREIGHT
(
... Column Definitions here ...
... With PK definition ...
ORMSTRID datatype NOT NULL PRIMARY KEY,
FreightCredit datatype,
FreightDebit datatype,
BudgtdFreightAmt datatype
)
INSERT INTO #FREIGHT

SELECT Client AS ORMSTRID,
SUM(Crdtamnt)AS FreightCredit,
SUM(debitamt) AS FreightDebit,
#Bdgt.Amount AS BudgtdFreightAmt
-- INTO #FREIGHT
FROM #GLCL
FULL JOIN #GL
ON #GL.ORMSTRID = #GLCL.Client
LEFT JOIN #Bdgt
ON #GLCL.Client = #Bdgt.ClientID
AND #Bdgt.DeptID = '03'
WHERE #GL.actindx IN
(
SELECT actindx
FROM #GL00100
WHERE LTRIM(Actnumbr_2) = '03'
and (CAST(RTRIM(LTRIM(actnumbr_3)) as integer) >= 100)
and (cast(rtrim(ltrim(actnumbr_3)) as Integer) <= 199)
)
GROUP BY ALL #GLCL.Client, #Bdgt.Amount

SELECT Client,
ClientName,
SUM(Laser) as Laser,
SUM(BudgtdLaser) AS BudgtdLaser,
SUM(Mail) AS Mail,
SUM(BudgtdMail) AS BudgtdMail,
SUM(Material) AS Material,
SUM(BudgtdMaterial) AS BudgtdMaterial,
SUM(Program) AS Program,
SUM(BudgtdProgram) AS BudgtdProgram,
SUM(EBiz) AS EBiz,
SUM(BudgtdEBiz) AS BudgtdEBiz,
SUM(Design) AS Design,
SUM(BudgtdDesign) AS BudgtdDesign,
SUM(Lodgement) AS Lodgement,
SUM(BudgtdLodgement) AS BudgtdLodgement,
SUM(Postage) AS Postage,
SUM(BudgtdPostage) AS BudgtdPostage,
SUM(Freight) AS Freight,
SUM(BudgtdFreight) AS BudgtdFreight
FROM
(
SELECT #GLCL.Client, #GLCL.ClientName,
ISNULL((#LASER.LaserCredit - #LASER.LaserDebit),0) AS Laser,
ISNULL(#LASER.BudgtdLaserAmt, 0) AS BudgtdLaser,
ISNULL((#MAIL.MailCredit - #MAIL.MailDebit),0) AS Mail,
ISNULL(#MAIL.BudgtdMailAmt, 0) AS BudgtdMail,
ISNULL((#MATERIAL.MaterialCredit - #MATERIAL.MaterialDebit),0) AS Material,
ISNULL(#MATERIAL.BudgtdMaterialAmt, 0) AS BudgtdMaterial,
ISNULL((#PROGRAM.ProgramCredit - #PROGRAM.ProgramDebit),0) AS Program,
ISNULL(#PROGRAM.BudgtdProgramAmt, 0) AS BudgtdProgram,
ISNULL((#EBIZ.EBCredit - #EBIZ.EBDebit),0) AS EBiz,
ISNULL(#EBIZ.BudgtdEBAmt, 0) AS BudgtdEBiz,
ISNULL((#DESIGN.DesignCredit - #DESIGN.DesignDebit),0) AS Design,
ISNULL(#DESIGN.BudgtdDesignAmt, 0) AS BudgtdDesign,
ISNULL((#LODGEMENT.LodgementCredit - #LODGEMENT.LodgementDebit),0) AS Lodgement,
ISNULL(#LODGEMENT.BudgtdLodgementAmt, 0) AS BudgtdLodgement,
ISNULL((#POSTAGE.PostageCredit - #POSTAGE.PostageDebit),0) AS Postage,
ISNULL(#POSTAGE.BudgtdPostageAmt, 0) AS BudgtdPostage,
ISNULL((#FREIGHT.FreightCredit - #FREIGHT.FreightDebit),0) AS Freight,
ISNULL(#FREIGHT.BudgtdFreightAmt, 0) AS BudgtdFreight
-- INTO #FINAL
FROM #GLCL
FULL JOIN #LASER
ON #GLCL.Client = #LASER.ORMSTRID
FULL JOIN #MAIL
ON #GLCL.Client = #MAIL.ORMSTRID
FULL JOIN #MATERIAL
ON #GLCL.Client = #MATERIAL.ORMSTRID
FULL JOIN #PROGRAM
ON #GLCL.Client = #PROGRAM.ORMSTRID
FULL JOIN #EBIZ
ON #GLCL.Client = #EBIZ.ORMSTRID
FULL JOIN #DESIGN
ON #GLCL.Client = #DESIGN.ORMSTRID
FULL JOIN #LODGEMENT
ON #GLCL.Client = #LODGEMENT.ORMSTRID
FULL JOIN #POSTAGE
ON #GLCL.Client = #POSTAGE.ORMSTRID
FULL JOIN #FREIGHT
ON #GLCL.Client = #FREIGHT.ORMSTRID
-- ORDER BY #GLCL.Client
) X
-- FROM #FINAL
GROUP BY Client, ClientName
ORDER BY Client

Kristen
Go to Top of Page

Wanderer
Master Smack Fu Yak Hacker

1168 Posts

Posted - 2004-07-16 : 07:07:42
Wow Kristen ... nice and complete work there ... beginning to think I should set up my helpdesk to automatically post SQL queries to SQLTeam, with a header 'attention - for Kristen'



*##* *##* *##* *##*

Chaos, Disorder and Panic ... my work is done here!
Go to Top of Page

Kristen
Test

22859 Posts

Posted - 2004-07-16 : 08:28:19
Ran it through the Formatter here, and then wrote a macro for my editor 'coz they're all basically the same changes.

When I see people post their code here, when asking for help, I just fail to understand how they can make Head'nor'Tail of it in the unformatted state they seem to keep it. They'd either learn fast, or be out of the door, here!

But its crying out for a proper rewrite. All that repetitive stuff could probably be done in one statement ...

And what about this for a peach:

SELECT actindx
FROM #GL00100
WHERE LTRIM(Actnumbr_2) = '19'
and (CAST(RTRIM(LTRIM(actnumbr_3)) as integer) >= 100)
and (cast(rtrim(ltrim(actnumbr_3)) as Integer) <= 199)

its already been put in a temprary table, but they didn't bother to cleanup [Actnumbr_2] and [actnumbr_3] when it went into the temporary table, NOR convert it to INT. Just unbelievable ... where did this poor blokes useless predecesor come from? I haven't got to the bottom of why the first has a capital 'A' and the second a lower case 'a' - let alone "opposing" case for "case(rtrim(ltrim" and "Integer"

And, whilst I'm at it, what about the gem of passing in the date parameters as VarChar? (or should that be VARCHAR - both styles seem to be permitted)

I mean ... P-LEASE

Kristen
Go to Top of Page

mk_garg20
Constraint Violating Yak Guru

343 Posts

Posted - 2004-07-18 : 18:24:16
Kristen,
I am really thankful to you for this detailed feedback.
Regards
Manoj
Go to Top of Page

mk_garg20
Constraint Violating Yak Guru

343 Posts

Posted - 2004-07-18 : 19:16:23
Kristen,
I have never worked on performance critical projects. Still Learning. You feedback is really important for me. I have gone through your feedback.

SELECT actindx
FROM #GL00100
WHERE LTRIM(Actnumbr_2) = '19'
and (CAST(RTRIM(LTRIM(actnumbr_3)) as integer) >= 100)
and (cast(rtrim(ltrim(actnumbr_3)) as Integer) <= 199)

You mean instead of CAST/TRIM/LTRIM in where condition, i should do all this stuff when i am creating temp table #GL00100. RIght?
Thanks
Manoj

Go to Top of Page

Kristen
Test

22859 Posts

Posted - 2004-07-19 : 04:54:16
"I am really thankful to you for this detailed feedback."

No problem, happy to help where I can. (But I'm appreciate knowing how much faster it becomes once you've finished improving it.)

"You mean instead of CAST/TRIM/LTRIM in where condition"

To be more exact I mean try not to do this on a column from the database, in a where clause.

If you do
SELECT *
FROM MyTable
WHERE MyColumn = @VARIABLE

then SQL will use an index for "MyColumn" if it can.

Whereas
SELECT *
FROM MyTable
WHERE CAST(TRIM(MUCK_ABOUT(MyColumn, ...))) = @VARIABLE

will force SQL to go through every single row in the table.

But its much more criminal in this case <vbg> because the data is coming from a temporary table, #GL00100, so all that needs to happen is that the CAST(TRIM(MUCK_ABOUT(...))) should have been done to the data as it went INTO #GL00100, to whit:

"i should do all this stuff when i am creating temp table #GL00100."

Yup, exactly so - although there are two parts, the CREATE should create columns of the type required later in the processing, and the INSERT should do the CAST/TRIM stuff

CREATE TABLE #GL00100
(
... Column Definitions here ...
... With PK definition ...
... Make sure that Actnumbr_2 and Actnumbr_3 are stored as INT types ...
... and remove all the TRIM and CAST on these columns below ...
... Make sure Actnumbr_2 and Actnumbr_3 are indexed ...
Actnumbr_2 int NOT NULL, -- I'm guessing that this should be INT
actnumbr_3 int NOT NULL

)

INSERT INTO #GL00100 (... other columns listed by name ..., Actnumbr_2, actnumbr_3)
SELECT ... other columns listed by name ...
LTRIM(Actnumbr_2) AS Actnumbr_2,
(CAST(RTRIM(LTRIM(actnumbr_3)) as integer) AS actnumbr_3

FROM CIMEL04.CDSYD.DBO.GL00100
WHERE LTRIM(Actnumbr_2) in ('12', '14', '03', '04', '07', '15', '17', '19', '11')
and (CAST(RTRIM(LTRIM(actnumbr_3)) as integer) >= 100)
and (cast(rtrim(ltrim(actnumbr_3)) as Integer) <= 199)

Kristen
Go to Top of Page

mk_garg20
Constraint Violating Yak Guru

343 Posts

Posted - 2004-07-19 : 22:33:28
Kristen,
In your previous feedbacks, You mentioned
"FULL JOIN expensive, is it required?"

Please tell me why it is expensive?

Related to this stored procedure i also found, CIMEL04 database is in other state and link is not very good that is also effecting performance of my stored procedure.
Thanks
Manoj


Go to Top of Page

Kristen
Test

22859 Posts

Posted - 2004-07-20 : 01:39:50
SQL uses an optimiser. It considers "Shall I use this index?" "What about that index?" and it estimates a "cost" for each one. The cost is in terms of CPU and Harddisk access etc. Hence one method may be more "expensive" than another. The optimiser takes the "cheapest" method and used that to make the query.

So ..
FULL OUTER JOIN is more expensive than OUTER JOIN.
OUTER JOIN is more expensive than JOIN.

So don;t use FULL OUTER JOIN if it isn;t needed (but it depends on your data)

Kristen
Go to Top of Page
   

- Advertisement -