July 25, 2012 at 9:21 am
Please excuse the double post for very similar question- I think I was on the wrong track with my previous post and want to pose a more general question.
I traced a process that repeatedly ran the same code IF EXISTS (select * from table where....) over the course of 5 hours. Initially, both duration and CPU were low. Duration about 10,000 microseconds, CPU close to 0. over time both measures gradually increased- running the exact same query. Any thoughts would be appreciated.
July 25, 2012 at 9:39 am
To post any performance related stuff, please check the article 'How to post performance problems - Gail Shaw]
http://www.sqlservercentral.com/articles/SQLServerCentral/66909/
~ Lokesh Vij
Link to my Blog Post --> www.SQLPathy.com[/url]
Follow me @Twitter
July 25, 2012 at 9:45 am
Without more detail it's hard to say, but if I had to guess... Is there a query with a sub-optimal execution plan against a table that is either growing in size over time, or is it using an index that is becoming rapidly fragmented? Are there other factors affecting it (blocking, other load on the server, etc.)?
Generally I would start with looking at the execution plan of this proc and go from there.
A.J.
DBA with an attitude
July 25, 2012 at 10:12 am
Definitely not a plan issue- it's reusing the same plan over time. Table is not changing.
It runs in a loop from a connection that remains open and does not do sp_reset_connection. Thinking this is some residual info being carried over or something like that. The proc is executed somethinkg like 200,000 times, so anything that increments could be the culprit.
July 25, 2012 at 10:20 am
lokeshvij (7/25/2012)
To post any performance related stuff, please check the article 'How to post performance problems - Gail Shaw]http://www.sqlservercentral.com/articles/SQLServerCentral/66909/
Thanks for this valuable input. If I were free to include DDL I would do so but I can not.
July 25, 2012 at 1:30 pm
As A.J. suggested have you ruled out index fragmentation by running a DMV query ( even though the table has not changed as per your feedback) ?
Also are the no of logical reads for the query remaining constant as well?
Try gathering waittype stats information, that may provide you with some useful clues.
July 25, 2012 at 1:42 pm
Vikrant S Patil (7/25/2012)
As A.J. suggested have you ruled out index fragmentation by running a DMV query ( even though the table has not changed as per your feedback) ?Also are the no of logical reads for the query remaining constant as well?
Try gathering waittype stats information, that may provide you with some useful clues.
Overall logical read rate decreased over time - presumably due to decreased rate of exeuction of the procs. I was not capturing reads per execution during the last run, but I will the next time.
There is no fragmentation issue.
Waits are all SOS_Scheduler_yield related.
July 25, 2012 at 3:30 pm
ok i cannot mention this with a great deal of authority but this points to a possible CPU contention \ pressure on your server.But then we are bound to see some sos_scheduler_yield waittypes even on systems where performance is fine and acceptable so this needs to investigated in detail.
it would really have been nice if we had some baseline stats when the query was running fine so that they could have been compared with current stats.
Following are a couple of URLs that may provide some information (if you already are not aware of the same)
http://blog.sqlauthority.com/2011/02/08/sql-server-sos_scheduler_yield-wait-type-day-8-of-28/[/url]
http://social.msdn.microsoft.com/forums/en-US/sqldatabaseengine/thread/e2ddf26f-f86c-4368-b4a7-17b2b7c64aa5/[/url]
July 25, 2012 at 4:11 pm
NJ-DBA (7/25/2012)
Please excuse the double post for very similar question- I think I was on the wrong track with my previous post and want to pose a more general question.I traced a process that repeatedly ran the same code IF EXISTS (select * from table where....) over the course of 5 hours. Initially, both duration and CPU were low. Duration about 10,000 microseconds, CPU close to 0. over time both measures gradually increased- running the exact same query. Any thoughts would be appreciated.
At least post the rest of the SELECT in the IF EXISTS. Otherwise, we're just guessing.
--Jeff Moden
Change is inevitable... Change for the better is not.
July 26, 2012 at 6:22 am
Jeff Moden (7/25/2012)
NJ-DBA (7/25/2012)
Please excuse the double post for very similar question- I think I was on the wrong track with my previous post and want to pose a more general question.I traced a process that repeatedly ran the same code IF EXISTS (select * from table where....) over the course of 5 hours. Initially, both duration and CPU were low. Duration about 10,000 microseconds, CPU close to 0. over time both measures gradually increased- running the exact same query. Any thoughts would be appreciated.
At least post the rest of the SELECT in the IF EXISTS. Otherwise, we're just guessing.
object names have been modified below. probably worth noting that this database runs in 8.0 compatability mode on SQL SErver 2008 SP1. The proc is called hundreds of thousands of times from a C# app running it in a loop (the loop is not a within SQL Server). It is reusing the same plan.
The query is:
IF EXISTS (select * from tablename where filename1=@filenameparam and typeidcol = @TypeIdparam and STATUS <> 5)
it's called from a proc like this:
------
CREATE procedure [dbo].[procname]
@TypeIdparam int,
@status int,
@filename2 varchar(500),
@filenameparam varchar(500),
@companyid int,
@remotedbName varchar(100)
AS
declare @nextDId int
declare @msg varchar(500)
declare @anotherId int
BEGIN TRY
begin transaction
-- first, check to see if this remote file name already exists in the inbound_file_control table and has not been pulled
IF EXISTS (select * from tablename where filename1=@filenameparam and typeidcol = @TypeIdparam and STATUS <> 5)
BEGIN
set @msg = 'return a message about: ' + @remoteFileName
RAISERROR (@msg, 16, 1)
END
<do some other stuff that is not relevant. we see this problem when if exists returns true >
END TRY
BEGIN CATCH
rollback transaction
declare @errorMessage nvarchar(4000)
set @errorMessage = ERROR_MESSAGE()
RAISERROR (@errorMessage, 16, 1)
END CATCH
-----
The table involved looks like this:
CREATE TABLE[dbo].[tablename](
idcol [int] IDENTITY(1,1) NOT NULL,
typeidcol [int] NOT NULL,
transferid [int] NOT NULL,
status [tinyint] NOT NULL,
filename1 [varchar](100) NOT NULL,
filename2 [varchar](200) NULL,
parentid [int] NULL,
foriegnid [int] NULL,
errordesc [varchar](1000) NULL,
timecol [datetime] NULL,
lastupdatedbyapp[varchar](50) NOT NULL,
lastupdateddt[datetime] NOT NULL,
companynum [int] NULL
) ON [PRIMARY]
SET ANSI_PADDING OFF
ALTER TABLE[dbo].[tablename] ADD [remotedbname] [varchar](100) NULL
/****** Object: Index [PK_tablename] Script Date: 07/26/2012 07:52:55 ******/
ALTER TABLE[dbo].[tablename] ADD CONSTRAINT [PK_tablename] PRIMARY KEY CLUSTERED
(
idcol ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
/****** Object: Index [IX_tablename_01] Script Date: 07/26/2012 07:52:55 ******/
CREATE NONCLUSTERED INDEX [IX_tablename_01] ON[dbo].[tablename]
(
typeidcol ASC,
status ASC,
lastupdateddtASC,
[remotedbname] ASC
)
INCLUDE ( transferid,
filename1) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 80) ON [PRIMARY]
GO
ALTER TABLE[dbo].[tablename] WITH CHECK ADD CONSTRAINT [FK_anothertable1] FOREIGN KEY(foriegnid)
REFERENCES [dbo].[anothertable1] (foriegnid)
GO
ALTER TABLE[dbo].[tablename] CHECK CONSTRAINT [FK_anothertable1]
IF EXISTS (select * from tablename where filename1=@filenameparam and typeidcol = @TypeIdparam and STATUS <> 5)
July 26, 2012 at 6:24 am
NJ-DBA (7/25/2012)
Vikrant S Patil (7/25/2012)
As A.J. suggested have you ruled out index fragmentation by running a DMV query ( even though the table has not changed as per your feedback) ?Also are the no of logical reads for the query remaining constant as well?
Try gathering waittype stats information, that may provide you with some useful clues.
Overall logical read rate decreased over time - presumably due to decreased rate of exeuction of the procs. I was not capturing reads per execution during the last run, but I will the next time.
There is no fragmentation issue.
Waits are all SOS_Scheduler_yield related.
To add some info, in a subsequent capture, while total logical reads on the server did go down, I added in "reads" to my trace and found that along with duration and CPU for the "if exists", reads went up over time... for the exact same query, using the exact same plan, on a table with very little changes if any.
July 26, 2012 at 6:29 am
NJ-DBA (7/26/2012)
Jeff Moden (7/25/2012)
NJ-DBA (7/25/2012)
Please excuse the double post for very similar question- I think I was on the wrong track with my previous post and want to pose a more general question.I traced a process that repeatedly ran the same code IF EXISTS (select * from table where....) over the course of 5 hours. Initially, both duration and CPU were low. Duration about 10,000 microseconds, CPU close to 0. over time both measures gradually increased- running the exact same query. Any thoughts would be appreciated.
At least post the rest of the SELECT in the IF EXISTS. Otherwise, we're just guessing.
object names have been modified below. probably worth noting that this database runs in 8.0 compatability mode on SQL SErver 2008 SP1. The proc is called hundreds of thousands of times from a C# app running it in a loop (the loop is not a within SQL Server). It is reusing the same plan.
The query is:
IF EXISTS (select * from tablename where filename1=@filenameparam and typeidcol = @TypeIdparam and STATUS <> 5)
it's called from a proc like this:
------
CREATE procedure [dbo].[procname]
@TypeIdparam int,
@status int,
@filename2 varchar(500),
@filenameparam varchar(500),
@companyid int,
@remotedbName varchar(100)
AS
declare @nextDId int
declare @msg varchar(500)
declare @anotherId int
BEGIN TRY
begin transaction
-- first, check to see if this remote file name already exists in the inbound_file_control table and has not been pulled
IF EXISTS (select * from tablename where filename1=@filenameparam and typeidcol = @TypeIdparam and STATUS <> 5)
BEGIN
set @msg = 'return a message about: ' + @remoteFileName
RAISERROR (@msg, 16, 1)
END
<do some other stuff that is not relevant. we see this problem when if exists returns true >
END TRY
BEGIN CATCH
rollback transaction
declare @errorMessage nvarchar(4000)
set @errorMessage = ERROR_MESSAGE()
RAISERROR (@errorMessage, 16, 1)
END CATCH
-----
The table involved looks like this:
CREATE TABLE[dbo].[tablename](
idcol [int] IDENTITY(1,1) NOT NULL,
typeidcol [int] NOT NULL,
transferid [int] NOT NULL,
status [tinyint] NOT NULL,
filename1 [varchar](100) NOT NULL,
filename2 [varchar](200) NULL,
parentid [int] NULL,
foriegnid [int] NULL,
errordesc [varchar](1000) NULL,
timecol [datetime] NULL,
lastupdatedbyapp[varchar](50) NOT NULL,
lastupdateddt[datetime] NOT NULL,
companynum [int] NULL
) ON [PRIMARY]
SET ANSI_PADDING OFF
ALTER TABLE[dbo].[tablename] ADD [remotedbname] [varchar](100) NULL
/****** Object: Index [PK_tablename] Script Date: 07/26/2012 07:52:55 ******/
ALTER TABLE[dbo].[tablename] ADD CONSTRAINT [PK_tablename] PRIMARY KEY CLUSTERED
(
idcol ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
/****** Object: Index [IX_tablename_01] Script Date: 07/26/2012 07:52:55 ******/
CREATE NONCLUSTERED INDEX [IX_tablename_01] ON[dbo].[tablename]
(
typeidcol ASC,
status ASC,
lastupdateddtASC,
[remotedbname] ASC
)
INCLUDE ( transferid,
filename1) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 80) ON [PRIMARY]
GO
ALTER TABLE[dbo].[tablename] WITH CHECK ADD CONSTRAINT [FK_anothertable1] FOREIGN KEY(foriegnid)
REFERENCES [dbo].[anothertable1] (foriegnid)
GO
ALTER TABLE[dbo].[tablename] CHECK CONSTRAINT [FK_anothertable1]
IF EXISTS (select * from tablename where filename1=@filenameparam and typeidcol = @TypeIdparam and STATUS <> 5)
also worth noting this is a high performance system- 24 cores, 120GB SQL Server memory.
Average CPU utilization on the box was under 25% during the run and no single processor spiked above 80%
July 26, 2012 at 6:35 am
also, we are aware there is a missing index that would cover the "if exists" query, but I dont think a missing index would make the duration increase over time... it would be slower, but constantly slower.
July 26, 2012 at 6:38 am
last one... I really should have waited and put this all as one post...
The app keeps the connection open for the duration of the run and does not do sp_reset_connection.
July 26, 2012 at 2:44 pm
ok this suggestion may seem a bit out of context but maybe you can execute a Update statistics for all tables with full scan and then attempt executing the proc \ query again.
I mean you are trying hard enough, this may not hurt too much.
Update statistics is an online operation but will take up some resources and cause overhead so you may to schedule it properly After statistics are updated you may possibly end up with a new plan when you execute the proc again
you did mention that the proc was using the same plan that worked fine earlier but updating statistics may still be worth a try.( if you have already not done that)
Viewing 15 posts - 1 through 15 (of 20 total)
You must be logged in to reply to this topic. Login to reply