Author |
Topic |
sudhan
Starting Member
6 Posts |
Posted - 2007-02-24 : 07:25:26
|
Hi i am using following stored procedure on MS SQL 2000 server .Its working fine.Now for better performance (related to execution speed , memory , recompilation problems)Is this stored procedure optimized or needs to be optimize?if it require to write in more better manner how can i modify?is any suggestions?thanks in advance...SET QUOTED_IDENTIFIER ON GOSET ANSI_NULLS ON GOif exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[cmdb_device_Paging]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)drop procedure [dbo].[cmdb_device_Paging]GOCREATE PROCEDURE cmdb_device_Paging ( @criteria varchar(15), @custID varchar(20), @pageSize varchar(5), @topValue varchar(5) ) AS SET NOCOUNT ONif @criteria = 'device'beginexec ( 'SELECT top '+@pageSize+ ' dev.DeviceId,dev.Address,dev.DeviceType,dev.MI,dev.DeviceName,dev.Hardware, dev.Software,dev.Community,dev.operation FROM Accounts ac INNER JOIN Device_PlaceHolder dev ON ac.SiteID = dev.SiteID AND ac.CustID = '''+@custID+'''' +' where dev.DeviceID not in( SELECT top '+@topValue+ ' dev.DeviceId FROM Accounts ac INNER JOIN Device_PlaceHolder dev ON ac.SiteID = dev.SiteID AND ac.CustID = '''+@custID+''''+' )' ) endif @criteria = 'managedDev'beginexec ( 'SELECT top '+@pageSize+ ' dev.DeviceID ,dev.Address ,dev.DeviceType ,dev.MI,dev.DeviceName ,dev.Hardware ,dev.Software ,dev.Community ,dev.Operation FROM Accounts ac INNER JOIN Device_PlaceHolder dev ON ac.SiteID = dev.SiteID AND ac.CustID = '''+@custID+'''' +' AND dev.operation IN('+'''MAD'''+','+'''MS'''+')'+' where dev.DeviceID not in ( SELECT top '+@topValue+ ' dev.DeviceID FROM Accounts ac INNER JOIN Device_PlaceHolder dev ON ac.SiteID = dev.SiteID AND ac.CustID = '''+@custID+''''+' AND dev.operation IN('+'''MAD'''+','+'''MS'''+')'+ ')' ) endif @criteria = 'unManagedDev'beginexec ( 'SELECT top '+@pageSize+ ' dev.DeviceID ,dev.Address ,dev.DeviceType ,dev.MI,dev.DeviceName ,dev.Hardware ,dev.Software ,dev.Community ,dev.Operation FROM Accounts ac INNER JOIN Device_PlaceHolder dev ON ac.SiteID = dev.SiteID AND ac.CustID = '''+@custID+'''' +' AND dev.Operation = '+ '''U'''+' where dev.DeviceID not in ( SELECT top '+@topValue+ ' dev.DeviceID FROM Accounts ac INNER JOIN Device_PlaceHolder dev ON ac.SiteID = dev.SiteID AND ac.CustID = '''+@custID+'''' +' AND dev.Operation = '+ '''U'''+' )' )endif @criteria = 'IgnoreDev'beginexec ( 'SELECT top '+@pageSize+ ' dev.DeviceID ,dev.Address ,dev.DeviceType ,dev.MI,dev.DeviceName ,dev.Hardware ,dev.Software ,dev.Community ,dev.Operation FROM Accounts ac INNER JOIN Device_PlaceHolder dev ON ac.SiteID = dev.SiteID AND ac.CustID = '''+@custID+'''' +' AND dev.Operation = '+ '''I'''+' where dev.DeviceID not in ( SELECT top '+@topValue+ ' dev.DeviceID FROM Accounts ac INNER JOIN Device_PlaceHolder dev ON ac.SiteID = dev.SiteID AND ac.CustID = '''+@custID+'''' +' AND dev.Operation = '+ '''I'''+' )' )endGOSET QUOTED_IDENTIFIER OFF GOSET ANSI_NULLS ON GO |
|
khtan
In (Som, Ni, Yak)
17689 Posts |
Posted - 2007-02-24 : 07:31:31
|
Why are you using dynamic SQL ?If it is only for the TOP <page size>, you can do thisdeclare @pagesize intselect @pagesize = 10set rowcount pagesizeselect * from yourtableset rowcount 0 And the queries are all very similar. You should be able to combine all into one. KH |
 |
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2007-02-24 : 10:25:31
|
And using TOP keyword has no meaning without an ORDER BY.Peter LarssonHelsingborg, Sweden |
 |
|
byrmol
Shed Building SQL Farmer
1591 Posts |
Posted - 2007-02-24 : 15:14:06
|
1) Use the ELSE IF construct to bypass extraneous branches2) From a readability/maintenance stand point.. create another variable (@TSQL) that contains the dynamic sql string and have only the one single EXEC function as the last statement.DavidMProduction is just another testing cycle |
 |
|
TonyTheDBA
Posting Yak Master
121 Posts |
Posted - 2007-02-26 : 08:03:46
|
IIRC the first time the SP runs the query optimiser determines the execution plan for the first Select thats run . . . If its running a different select the second time then it discards the stored query plan and recompiles it.The rule I give my developers "One stored procedure, One SQL Statement" (any more than that and they get really confused The other thing you can do is to useSET ROWCOUNT = @PageSize[Your Query]SET ROWCOUNT = 0Instead of the Select TOP @PageSize statement-- RegardsTony The DBA |
 |
|
sudhan
Starting Member
6 Posts |
Posted - 2007-02-26 : 08:40:28
|
hithanks for reply, whatever you suggest its fine & i will give it tryBUTWhen i check in more detail then found that in each query i am using " NOT IN "when topValue in inner query increased more than 1 lac then it will very very slow.So now i want to remove NOT IN with IN or have to use CURSUR so how can i do that?and if i rplace NOT IN with NOT EXIST then also it will doing same --like 1st it will execute inner query and then it will compare primary key whether it is present in ids obtained in inner query .am i right?thaks in advance... |
 |
|
harsh_athalye
Master Smack Fu Yak Hacker
5581 Posts |
Posted - 2007-02-26 : 08:51:33
|
I think if you convert NOT IN to NOT EXISTS operator, you don't need TOP clause at all and neither dynamic sql also.Harsh AthalyeIndia."The IMPOSSIBLE is often UNTRIED" |
 |
|
sudhan
Starting Member
6 Posts |
Posted - 2007-02-26 : 09:04:00
|
when i run sample query given below then it giving syntax error -Msg 156, Level 15, State 1, Line 2Incorrect syntax near the keyword 'EXISTS'.select top 50 * from device_placeholder where deviceidNOT EXISTS(select top 20000 deviceid from device_placeholder) |
 |
|
sudhan
Starting Member
6 Posts |
Posted - 2007-02-26 : 09:06:27
|
missed to mentin i m using MS SQL server 2000 !! |
 |
|
harsh_athalye
Master Smack Fu Yak Hacker
5581 Posts |
Posted - 2007-02-26 : 09:08:29
|
I don't get your sample query? You are trying to select deviceids from device_placeholder table which are not in device_placeholder table itself ??? What does that mean?Anyway your use of EXISTS operator is wrong syntactically:Select * from t1Where not Exists (select * from t2 where t2.col = t1.col) Harsh AthalyeIndia."The IMPOSSIBLE is often UNTRIED" |
 |
|
sudhan
Starting Member
6 Posts |
Posted - 2007-02-26 : 09:27:57
|
i am implementing this query for pagination and meaning of my qyery is for each request it will fetch the next record set (of size equal to outer query top value) which was not present in previous record set of same query. |
 |
|
khtan
In (Som, Ni, Yak)
17689 Posts |
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2007-02-26 : 10:04:26
|
[code]CREATE PROCEDURE cmdb_device_Paging( @Criteria VARCHAR(15), @CustID VARCHAR(20), @Page INT, @PageSize INT)AS SET NOCOUNT ONDECLARE @Paging TABLE (DeviceID INT, RecID INT IDENTITY(0, 1))INSERT @Paging ( DeviceID )SELECT dev.DeviceId,FROM Accounts AS acINNER JOIN Device_PlaceHolder AS dev ON dev.SiteID = ac.SiteIDWHERE ac.CustID = @CustID AND 1 = CASE WHEN @Criteria = 'device' THEN 1 WHEN @Criteria = 'managedDev' AND dev.operation IN ('MAD','MS') THEN 1 WHEN @Criteria = 'unManagedDev' AND dev.operation = 'U' THEN 1 WHEN @Criteria = 'IgnoreDev' AND dev.operation = 'I' THEN 1 ELSE 0 ENDORDER BY dev.DeviceIdDELETEFROM @PagingWHERE RecID / @PageSize <> @Page - 1SELECT dev.DeviceId, dev.Address, dev.DeviceType, dev.MI, dev.DeviceName, dev.Hardware, dev.Software, dev.Community, dev.operationFROM Device_PlaceHolder AS devINNER JOIN @Paging AS p ON p.DeviceId = dev.DeviceIDORDER BY dev.DeviceId[/code] |
 |
|
Jeff Moden
Aged Yak Warrior
652 Posts |
Posted - 2007-02-28 : 00:23:06
|
The code the orginal requestor posted looks like GUI "paging" code... especially in light of the NOT IN. In the presence of correct indicies, it'll be lightning quick even though it's dynamic SQL.It's been my experience that NOT IN's are a wee bit faster than outer joins with Null detects... haven't tried the NOT EXISTS because that involves a correlated subquery. Could be very fast if indexed correctly but I generally try to avoid correlated subqueries that work as RBAR.--Jeff Moden |
 |
|
|