sql server - Execute query command (dynamic sql) runs faster than ordinary query -
why second query execute
command runs ~4 times faster first query without one? how can solve problem?
why additional table (workatable) created in second case?
variables:
declare @count int, @followerid bigint set @count=1024 set @followerid=10
first query (usual query):
select top (@count) photo.* photo exists (select accountid follower follower.followerid=@followerid , follower.accountid = photo.accountid) , photo.closed='false' order photo.createdate desc
log:
sql server parse , compile time: cpu time = 0 ms, elapsed time = 7 ms.
sql server execution times: cpu time = 0 ms, elapsed time = 0 ms.
table 'photo'. scan count 952, logical reads 542435, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
table 'follower'. scan count 1, logical reads 7, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
sql server execution times: cpu time = 1466 ms, elapsed time = 9620 ms.
execution plan:
second query (the same query execute
):
exec ('select top (' +@count + ') photo.* photo exists ( select accountid follower follower.followerid=' +@followerid + ' , follower.accountid = photo.accountid) , photo.closed=''false'' order photo.createdate desc')
log:
sql server parse , compile time: cpu time = 0 ms, elapsed time = 0 ms.
sql server execution times: cpu time = 0 ms, elapsed time = 0 ms.
sql server execution times: cpu time = 0 ms, elapsed time = 0 ms. sql server parse , compile time: cpu time = 25 ms, elapsed time = 25 ms.
table 'worktable'. scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
table 'photo'. scan count 952, logical reads 542707, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
table 'follower'. scan count 6, logical reads 9, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
table 'worktable'. scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
sql server execution times: cpu time = 1374 ms, elapsed time = 2140 ms.
sql server execution times: cpu time = 1405 ms, elapsed time = 2165 ms.
this because second query (depending on context of first query) more optimizable, since variables become inline constants. compare:
declare @count int, @followerid bigint set @count=1024 set @followerid=10 select top (@count) photo.* photo exists (select accountid follower follower.followerid=@followerid , follower.accountid = photo.accountid) , photo.closed='false' order photo.createdate desc
with:
select top (1024) photo.* photo exists (select accountid follower follower.followerid=10 , follower.accountid = photo.accountid) , photo.closed='false' order photo.createdate desc
this true if first query part of stored proc, variables arguments , particular query optimized different parameter values when stored proc compiled.
Comments
Post a Comment