February 21, 2005 at 12:41 pm
Guys,
I'm having a performance issue with one of our production database. I've setup performance monitoring using perfmon and profiler. Here's the result of the perfmon:
Counter Name Avg
Full Scans 30
SQL Re-compilations 16
Cache Hit Ratio 38
Buffer Cache Hit Ratio 99
Memory Grants Pending 0
SQL Compilations 24
Processor Time 40
Disk Reads(C,D) 0
Disk Reads(I) 0
Disk Reads(H) 15
Disk Reads(G) 0
Disk Reads(F) 0
Disk Writes(C,D) 5
Disk Writes(I) 0
Disk Writes(H) 5
Disk Writes(G) 1
Disk Writes(F) 0
%Privileged Time 0.6
Processor Queue Length 10
Can you tell me or interpret the result for me? I think there's a bottle with the CPU and I think there's alot of recompilation/compilation going on to affect CPU usage. What do you guys think? I really need to figure out by today so please SQL GURUs help me out.
Thanks!
Dex
February 21, 2005 at 3:54 pm
You may need to back up a bit and I would bet that you don't have a quick fix on your hands. From my experience, most performance issues are not related as much to hardware as they are the application and database design. From what I see in your results there are two things that jump out at me.
Your CPU average doesn't jump out and cause any alarm. At least as far as I am concerned. Are you seeing spikes in CPU utilization? Anyway, if the CPU is having problems then it is most likely application and design driven.
You probably need to be more specific with the applications and the performance issues. One bad query can slow every one else. I hear the "database is slow" so many times and 9 times out of 10 it is application and database design specific.
One more thing...I like how your disks are spread out. Maybe you could take more advantage of this and spread the i/o around with filegroups and files. Why the writes on the C:\ drive? Are you paging?
"Keep Your Stick On the Ice" ..Red Green
February 22, 2005 at 1:51 am
As Jeff just told you, at the really first step you have to check the indexes.
Use the Profiler to check which are the statements using the most of the ressources (either Duration or CPU or disk).
Afterwords you can execute those queries in QA where you can check the access plan. So you can see, whether your query is usung indexes or not.
Bye
Gabor
February 22, 2005 at 2:47 am
I'm using this to determine I/O, CPU and memory issues (we have performance issues with SQL trace). Just change the job to run at a time of your performance issues and you can also change the execution time to every minute (I'm running every 2 minutes at this stage). Note that only sessions connected for 4 minutes (if you leave the job to run every 2 minutes) will be logged in the stats table and I'm using GBEMonitor as a database (change or create) ... you can figure the rest out ... have included a SQL to display the results at the end of the post.
Christo Pretorius
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[Database_session_perf]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [dbo].[Database_session_perf]
GO
CREATE TABLE [dbo].[Database_session_perf] (
[spid] [smallint] NOT NULL ,
[dbid] [smallint] NOT NULL ,
[cpu] [int] NOT NULL ,
[physical_io] [bigint] NOT NULL ,
[memusage] [int] NOT NULL ,
[hostname] [nvarchar] (128) NOT NULL ,
[hostprocess] [nchar] (8) NOT NULL ,
[loginname] [nvarchar] (128) NOT NULL ,
[statdatetime] [datetime] NOT NULL
) ON [PRIMARY]
GO
CREATE CLUSTERED INDEX [IX_Database_session_perf] ON [dbo].[Database_session_perf]([statdatetime]) WITH FILLFACTOR = 98 ON [PRIMARY]
GO
ALTER TABLE [dbo].[Database_session_perf] WITH NOCHECK ADD
CONSTRAINT [DF_Database_session_perf_statdatetime] DEFAULT (getdate()) FOR [statdatetime]
GO
BEGIN TRANSACTION
DECLARE @JobID BINARY(16)
DECLARE @ReturnCode INT
SELECT @ReturnCode = 0
IF (SELECT COUNT(*) FROM msdb.dbo.syscategories WHERE name = N'Database Monitoring') < 1
EXECUTE msdb.dbo.sp_add_category @name = N'Database Monitoring'
-- Delete the job with the same name (if it exists)
SELECT @JobID = job_id
FROM msdb.dbo.sysjobs
WHERE (name = N'Database Session Perf')
IF (@JobID IS NOT NULL)
BEGIN
-- Check if the job is a multi-server job
IF (EXISTS (SELECT *
FROM msdb.dbo.sysjobservers
WHERE (job_id = @JobID) AND (server_id <> 0)))
BEGIN
-- There is, so abort the script
RAISERROR (N'Unable to import job ''Database Session Perf'' since there is already a multi-server job with this name.', 16, 1)
GOTO QuitWithRollback
END
ELSE
-- Delete the [local] job
EXECUTE msdb.dbo.sp_delete_job @job_name = N'Database Session Perf'
SELECT @JobID = NULL
END
BEGIN
-- Add the job
EXECUTE @ReturnCode = msdb.dbo.sp_add_job @job_id = @JobID OUTPUT , @job_name = N'Database Session Perf', @owner_login_name = N'sa', @description = N'No description available.', @category_name = N'Database Monitoring', @enabled = 1, @notify_level_email = 0, @notify_level_page = 0, @notify_level_netsend = 0, @notify_level_eventlog = 2, @delete_level= 0
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
-- Add the job steps
EXECUTE @ReturnCode = msdb.dbo.sp_add_jobstep @job_id = @JobID, @step_id = 1, @step_name = N'Step 1', @command = N'set nocount on
go
insert into GBEMonitor.dbo.database_session_perf
([spid], [dbid], [cpu], [physical_io], [memusage], [hostname], [hostprocess], [loginname])
select [spid], [dbid], [cpu], [physical_io], [memusage], [hostname], [hostprocess], [loginame]
from sysprocesses (nolock)
go
set nocount off
go', @database_name = N'master', @server = N'', @database_user_name = N'', @subsystem = N'TSQL', @cmdexec_success_code = 0, @flags = 0, @retry_attempts = 0, @retry_interval = 1, @output_file_name = N'', @on_success_step_id = 0, @on_success_action = 1, @on_fail_step_id = 0, @on_fail_action = 2
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
EXECUTE @ReturnCode = msdb.dbo.sp_update_job @job_id = @JobID, @start_step_id = 1
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
-- Add the job schedules
EXECUTE @ReturnCode = msdb.dbo.sp_add_jobschedule @job_id = @JobID, @name = N'Schedule 1', @enabled = 1, @freq_type = 8, @active_start_date = 20050219, @active_start_time = 0, @freq_interval = 97, @freq_subday_type = 4, @freq_subday_interval = 2, @freq_relative_interval = 0, @freq_recurrence_factor = 1, @active_end_date = 99991231, @active_end_time = 235959
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
-- Add the Target Servers
EXECUTE @ReturnCode = msdb.dbo.sp_add_jobserver @job_id = @JobID, @server_name = N'(local)'
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
END
COMMIT TRANSACTION
GOTO EndSave
QuitWithRollback:
IF (@@TRANCOUNT > 0) ROLLBACK TRANSACTION
EndSave:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
and then to sellect the results (examples and you need to customize):
SELECT a.spid, b.statdatetime, a.dbid, a.hostname, a.loginname,
b.cpu - a.cpu as CPU,
b.physical_io - a.physical_io as PHYSICAL_IO,
b.[memusage] - a.[memusage] as MEMORY
FROM GBEMonitor.dbo.Database_session_perf a (nolock), GBEMonitor.dbo.Database_session_perf b (nolock)
WHERE
--(a.dbid = 5)
--(a.hostname='B2CAPP06')
(b.dbid=a.dbid)
and (b.spid=a.spid)
and (b.hostname=a.hostname)
and (b.loginname=a.loginname)
and (a.statdatetime<b.statdatetime)
and (b.statdatetime-0.0017<a.statdatetime)
and (b.cpu-a.cpu>=0)
and (b.physical_io-a.physical_io>=0)
and (b.[memusage]-a.[memusage]>=0)
and ((b.cpu - a.cpu > 0)
or (b.physical_io - a.physical_io > 0)
or (b.[memusage] - a.[memusage] > 0)
)
--b.statdatetime > '2005-02-19 14:15:00.000'
--b.statdatetime < '2005-02-19 14:19:00.000'
ORDER BY b.statdatetime, a.dbid, a.hostname, a.loginname
--select * from sysdatabases
select * from Database_session_perf (nolock)
where dbid = 5 and spid = 75 and hostname = 'B2CAPP06' and statdatetime > '2005-02-19 14:15:00.000' and statdatetime < '2005-02-19 14:19:00.000'
February 22, 2005 at 8:10 am
Thanks Guys! I really appreciate your responses! I think I've narrow down the problems. Since our other DBA put all the system databases on the same drive as the production database(H) and our third party program creates alot of temporary tables on most of the SP's, I think moving the tempDB or all the system databases will alleviate the disk contention a little bit. After that, I'll do a SQL trace to find all long running queries and we'll get back to the vendors to try to see if they can do anything on there end since I can't change anything on the DB side because it'll void our contract. I'll confirm it tomorrow if it's really a disk contention on drive H because I'll be talking to a SAN engineer to if there's any hotspots on the spindles that makes up drive H.
February 22, 2005 at 9:03 am
Dexter...
Could you keep us posted as to your findings and the type of SAN your using? I am guessing...and bear in mind this is just a guess..that there aren't issues with the spindles since the SAN Luns are made of of so many smaller disks. What I am hoping you might find is that there is either and issue from the nic via fiber to the SAN and/or the i/o threads on the server itself are bottlenecking.
I need to test a proof of concept myself, but would enjoy reading about what you find.
Thanks...
"Keep Your Stick On the Ice" ..Red Green
February 22, 2005 at 10:17 am
Sure do Jeff...I think we're using DMX 800 SAN Storage System. For the H drive, it's in a raid 5 configuration and the log files(G) is raid 1. I agree on you on that spindles are made up of so many smaller disks. I think and i'm guessing also that the i/o threads on the server are bottlenecking. The program is doing it's business rule implementation and processing on majority of it's SP's....in short doing alot of processing on a temporary table. Because tempdb resides on the same drive as the prod DB, i think it's safe to way it's one of the cause of the performance degration on the server. I did a sql trace yesterday and I'm analyzing all the SP's and SqL statement right now to see if it's optimize or not.
Also, the front end is a web app so the combination of reasons above and # of concurrent users have to do with the performance degradation.
February 23, 2005 at 1:01 pm
ok our SAN engineer looked at all the hypers and yes there were a couple of them that have a lot of hotspots around that time of performance degradation. I told him about the situation and he told me that could be the problem. He's creating two new volumes for me so that I can put the system database to one volume and system logs to another volume for performance reason. Thanks for all your help SQL Gurus! I'll do baseline analysis before and after I move the system databases to see the benefits of it. Thanks again!
Viewing 8 posts - 1 through 7 (of 7 total)
You must be logged in to reply to this topic. Login to reply