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 |
|
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.ThanksManojCREATE PROCEDURE [dbo].[sp_Get_DynSalesAndBudgetFigures] (@StartDate AS VarChar(10), @EndDate AS VarChar(10))AS /*Testing variablesDECLARE @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 variablesSET @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 yearIF 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 ENDELSE 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, DeptIDSELECT * INTO #GL FROM CIMEL04.CDSYD.DBO.GL20000 GL20000WHERE GL20000.trxdate < (' + @EDate + ' + 1) AND GL20000.trxdate >= ' + @SDate + 'ORDER BY GL20000.ORMSTRIDSELECT DISTINCT RM00101.Custnmbr AS Client, RM00101.CustName AS ClientName INTO #GLCL FROM CIMEL04.CDSYD.DBO.RM00101 RM00101 ORDER BY RM00101.CustnmbrSELECT ClientID, SUM(Amount) AS AmountINTO #BdgLaser FROM #Bdgt WHERE (#Bdgt.DeptID = ''14'' OR #Bdgt.DeptID = ''09'') GROUP BY ClientIDSELECT * 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 BudgtdLaserAmtINTO #LASER FROM #GLCL FULL JOIN #GL ON #GL.ORMSTRID = #GLCL.Client LEFT JOIN #BdgLaser ON #GLCL.Client = #BdgLaser.ClientIDWHERE #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.AmountSELECT Client AS ORMSTRID, SUM(Crdtamnt)AS MailCredit, SUM(debitamt) AS MailDebit, #Bdgt.Amount AS BudgtdMailAmtINTO #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.AmountSELECT Client AS ORMSTRID, SUM(Crdtamnt)AS MaterialCredit, SUM(debitamt) AS MaterialDebit, #Bdgt.Amount AS BudgtdMaterialAmtINTO #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.AmountSELECT Client AS ORMSTRID, SUM(Crdtamnt)AS ProgramCredit, SUM(debitamt) AS ProgramDebit, #Bdgt.Amount AS BudgtdProgramAmtINTO #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.AmountSELECT Client AS ORMSTRID, SUM(Crdtamnt)AS EBCredit, SUM(debitamt) AS EBDebit, #Bdgt.Amount AS BudgtdEBAmtINTO #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.AmountSELECT Client AS ORMSTRID, SUM(Crdtamnt)AS DesignCredit, SUM(debitamt) AS DesignDebit, #Bdgt.Amount AS BudgtdDesignAmtINTO #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.AmountSELECT Client AS ORMSTRID, SUM(Crdtamnt)AS LodgementCredit, SUM(debitamt) AS LodgementDebit, #Bdgt.Amount AS BudgtdLodgementAmtINTO #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.AmountSELECT Client AS ORMSTRID, SUM(Crdtamnt)AS PostageCredit, SUM(debitamt) AS PostageDebit, #Bdgt.Amount AS BudgtdPostageAmtINTO #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.AmountSELECT Client AS ORMSTRID, SUM(Crdtamnt)AS FreightCredit, SUM(debitamt) AS FreightDebit, #Bdgt.Amount AS BudgtdFreightAmtINTO #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.AmountSELECT #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 BudgtdFreightINTO #FINAL FROM #GLCL FULL JOIN #LASER ON #GLCL.Client = #LASER.ORMSTRID FULL JOIN #MAIL ON #GLCL.Client = #MAIL.ORMSTRIDFULL JOIN #MATERIAL ON #GLCL.Client = #MATERIAL.ORMSTRID FULL JOIN #PROGRAM ON #GLCL.Client = #PROGRAM.ORMSTRIDFULL JOIN #EBIZ ON #GLCL.Client = #EBIZ.ORMSTRID FULL JOIN #DESIGN ON #GLCL.Client = #DESIGN.ORMSTRIDFULL JOIN #LODGEMENT ON #GLCL.Client = #LODGEMENT.ORMSTRID FULL JOIN #POSTAGE ON #GLCL.Client = #POSTAGE.ORMSTRIDFULL 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 BudgtdFreightFROM #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 GL20000Don'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 #GLSELECT a,b,c FROM CIMEL04.CDSYD.DBO.GL20000 GL20000Also, 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 JOINFinally 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 |
 |
|
|
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.ThanksManoj |
 |
|
|
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 |
 |
|
|
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 |
 |
|
|
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 |
 |
|
|
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 |
 |
|
|
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.ThanksManoj |
 |
|
|
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 tooI 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 variablesDECLARE @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 variablesSET @StartDate = '01/08/2003'SET @EndDate = '31/08/2003'*/SET @SDate = CONVERT(DATETIME, @StartDate, 103)IF LEN(LTRIM(RTRIM(@EndDate))) = 0SET @EDate = CONVERT(DATETIME, @StartDate, 103) + 6 ELSESET @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 yearIF 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)) < 7SET @FinYear = YEAR(CONVERT(DATETIME, @StartDate, 103))ELSESET @FinYear = YEAR(CONVERT(DATETIME, @StartDate, 103)) + 1ENDELSEBEGIN-- 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)) < 7SET @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, DeptIDCREATE TABLE #GL( ... Column Definitions here ... ... With PK definition ...)INSERT INTO #GLSELECT * ... column list here ...-- INTO #GLFROM CIMEL04.CDSYD.DBO.GL20000 GL20000WHERE GL20000.trxdate < ( @EDate + 1) AND GL20000.trxdate >= @SDate ORDER BY GL20000.ORMSTRIDCREATE TABLE #GLCL( ... Column Definitions here ... ... With PK definition ... Client datatype NOT NULL PRIMARY KEY, ClientName datatype)INSERT INTO #GLCLSELECT DISTINCT RM00101.Custnmbr AS Client, RM00101.CustName AS ClientName -- INTO #GLCL FROM CIMEL04.CDSYD.DBO.RM00101 RM00101 ORDER BY RM00101.CustnmbrCREATE TABLE #BdgLaser( ... Column Definitions here ... ... With PK definition ... ClientID datatype NOT NULL PRIMARY KEY, Amount datatype)INSERT INTO #BdgLaserSELECT ClientID, SUM(Amount) AS Amount-- INTO #BdgLaserFROM #Bdgt WHERE ( #Bdgt.DeptID = '14' OR #Bdgt.DeptID = '09')GROUP BY ClientIDCREATE 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 #GL00100SELECT * ... column list here ...-- INTO #GL00100FROM CIMEL04.CDSYD.DBO.GL00100 -- TRIM here is bad for performanceWHERE 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 #LASERSELECT Client AS ORMSTRID, SUM(Crdtamnt)AS LaserCredit, SUM(debitamt) AS LaserDebit, #BdgLaser.Amount AS BudgtdLaserAmt-- INTO #LASERFROM #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.AmountCREATE TABLE #MAIL( ... Column Definitions here ... ... With PK definition ... ORMSTRID datatype NOT NULL PRIMARY KEY, MailCredit datatype, MailDebit datatype, BudgtdMailAmt datatype)INSERT INTO #MAILSELECT Client AS ORMSTRID, SUM(Crdtamnt)AS MailCredit, SUM(debitamt) AS MailDebit, #Bdgt.Amount AS BudgtdMailAmt-- INTO #MAILFROM #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.AmountCREATE TABLE #MATERIAL( ... Column Definitions here ... ... With PK definition ... ORMSTRID datatype NOT NULL PRIMARY KEY, MaterialCredit datatype, MaterialDebit datatype, BudgtdMaterialAmt datatype)INSERT INTO #MATERIALSELECT Client AS ORMSTRID, SUM(Crdtamnt)AS MaterialCredit, SUM(debitamt) AS MaterialDebit, #Bdgt.Amount AS BudgtdMaterialAmtFROM #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.AmountCREATE TABLE #PROGRAM( ... Column Definitions here ... ... With PK definition ... ORMSTRID datatype NOT NULL PRIMARY KEY, MaterialCredit datatype, MaterialDebit datatype, BudgtdMaterialAmt datatype)INSERT INTO #PROGRAMSELECT Client AS ORMSTRID, SUM(Crdtamnt)AS ProgramCredit, SUM(debitamt) AS ProgramDebit, #Bdgt.Amount AS BudgtdProgramAmtFROM #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.AmountCREATE TABLE #EBIZ( ... Column Definitions here ... ... With PK definition ... ORMSTRID datatype NOT NULL PRIMARY KEY, EBCredit datatype, EBDebit datatype, BudgtdEBAmt datatype)INSERT INTO #EBIZSELECT Client AS ORMSTRID, SUM(Crdtamnt)AS EBCredit, SUM(debitamt) AS EBDebit, #Bdgt.Amount AS BudgtdEBAmt-- INTO #EBIZFROM #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.AmountCREATE TABLE #EBIZ( ... Column Definitions here ... ... With PK definition ... ORMSTRID datatype NOT NULL PRIMARY KEY, DesignCredit datatype, DesignDebit datatype, BudgtdDesignAmt datatype)INSERT INTO #EBIZSELECT Client AS ORMSTRID, SUM(Crdtamnt)AS DesignCredit, SUM(debitamt) AS DesignDebit, #Bdgt.Amount AS BudgtdDesignAmt-- INTO #DESIGNFROM #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.AmountCREATE TABLE #LODGEMENT( ... Column Definitions here ... ... With PK definition ... ORMSTRID datatype NOT NULL PRIMARY KEY, DesignCredit datatype, DesignDebit datatype, BudgtdDesignAmt datatype)INSERT INTO #LODGEMENTSELECT Client AS ORMSTRID, SUM(Crdtamnt)AS LodgementCredit, SUM(debitamt) AS LodgementDebit, #Bdgt.Amount AS BudgtdLodgementAmt-- INTO #LODGEMENTFROM #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.AmountCREATE TABLE #POSTAGE( ... Column Definitions here ... ... With PK definition ... ORMSTRID datatype NOT NULL PRIMARY KEY, PostageCredit datatype, PostageDebit datatype, BudgtdPostageAmt datatype)INSERT INTO #POSTAGESELECT Client AS ORMSTRID, SUM(Crdtamnt)AS PostageCredit, SUM(debitamt) AS PostageDebit, #Bdgt.Amount AS BudgtdPostageAmt-- INTO #POSTAGEFROM #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.AmountCREATE TABLE #FREIGHT( ... Column Definitions here ... ... With PK definition ... ORMSTRID datatype NOT NULL PRIMARY KEY, FreightCredit datatype, FreightDebit datatype, BudgtdFreightAmt datatype)INSERT INTO #FREIGHTSELECT Client AS ORMSTRID, SUM(Crdtamnt)AS FreightCredit, SUM(debitamt) AS FreightDebit, #Bdgt.Amount AS BudgtdFreightAmt-- INTO #FREIGHTFROM #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.AmountSELECT 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 BudgtdFreightFROM( 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 #FINALGROUP BY Client, ClientName ORDER BY Client Kristen |
 |
|
|
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! |
 |
|
|
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-LEASEKristen |
 |
|
|
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.RegardsManoj |
 |
|
|
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?ThanksManoj |
 |
|
|
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 doSELECT *FROM MyTableWHERE MyColumn = @VARIABLEthen SQL will use an index for "MyColumn" if it can.WhereasSELECT *FROM MyTableWHERE CAST(TRIM(MUCK_ABOUT(MyColumn, ...))) = @VARIABLEwill 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 stuffCREATE 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_3FROM 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 |
 |
|
|
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.ThanksManoj |
 |
|
|
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 |
 |
|
|
|
|
|
|
|