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.

 All Forums
 Old Forums
 CLOSED - General SQL Server
 Getting basic performance metrics

Author  Topic 

Glockenspiel
Yak Posting Veteran

50 Posts

Posted - 2002-06-24 : 17:37:07
I'm trying to get some baseline performance metrics on uptime, CPU usage, and io for my SQL Server. Here's what I've started -- just curious if anyone else has some better ideas or may have gone down this path before me. Thanks!

SELECT
CONVERT(VARCHAR(24),crdate,113) AS time_restart,
CONVERT(VARCHAR(24),GETDATE(),113) AS time_now,
DATEDIFF(mi,crdate,GETDATE()) AS minutes_since_restart,
@@cpu_busy/15000.0 AS minutes_cpu_busy,
@@io_busy/15000.0 AS minutes_io_busy,
@@idle/15000.0 AS minutes_idle,
(@@cpu_busy+@@io_busy+@@idle)/15000.0 AS minutes_since_restart2,
@@connections AS connections
FROM master..sysdatabases
WHERE name = 'tempdb'

Sample Results Set:

time_restart time_now minutes_since_restart minutes_cpu_busy minutes_io_busy minutes_idle minutes_since_restart2 connections
------------------------ ------------------------ --------------------- -------------------- -------------------- -------------------- ---------------------- -----------
23 Jun 2002 19:34:21:623 25 Jun 2002 10:15:49:077 2321 182.6625333 10.9890666 2128.1510666 2321.8026666 25961

Edited by - Glockenspiel on 06/25/2002 11:15:26

Page47
Master Smack Fu Yak Hacker

2878 Posts

Posted - 2002-06-25 : 08:53:13
This is more of an abstract answer than I am sure you would like, but....when you begin the task of performance tuning, no matter how basic, it is vital that you have a goal in mind. This query if nifty, and it may very well be what you want, however, since you are asking, I'd bet you are not sure what you want. The query/perfmon/trace/statistics is the easy part, deciding what exactly you want to measure is a bit more difficult . . .

<O>
Go to Top of Page

Glockenspiel
Yak Posting Veteran

50 Posts

Posted - 2002-06-25 : 10:31:15
quote:
This is more of an abstract answer than I am sure you would like, but....when you begin the task of performance tuning, no matter how basic, it is vital that you have a goal in mind.


We're looking for a nice and easy, simple, and somewhat foolproof way to get some baseline data on CPU utilization and up-time (time since last restart). The fewer "moving parts" the better (i.e., we don't want to set up a PerfMon or Profiler to run on this box.)

Go to Top of Page

Glockenspiel
Yak Posting Veteran

50 Posts

Posted - 2002-06-25 : 11:27:02
I've updated the prior post; it looks like you have to divide the system statistical functions by 15000.0 to get values in minutes (somebody please explain this one to me). Also, it looks like @@cpu_busy + @@io_busy + @@idle add up correctly this way. This obviates the need to use tempdb's crdate as the start date since the ms since service started can be computed backwards by multiplying by -4 (again, somebody please explain this one to me).

Simply:

SELECT
@@cpu_busy/15000.0 AS minutes_cpu_busy,
@@io_busy/15000.0 AS minutes_io_busy,
@@idle/15000.0 AS minutes_idle,
(@@cpu_busy+@@io_busy+@@idle)/15000.0 AS minutes_since_restart,
DATEADD(ms,-4*(@@cpu_busy+@@io_busy+@@idle),GETDATE()) AS computed_startup_time

And viola, the numbers and times make sense!!!!

Go to Top of Page

Glockenspiel
Yak Posting Veteran

50 Posts

Posted - 2002-06-25 : 11:39:59
OK; newsflash... this seems to be CPU-related. In other words:

multiply by -4 if your machine is 8-way
multiply by -8 if your machine is 4-way
multiply by -16 if your machine is 2-way
multiply by -32 if your machine is 1-way



Edited by - Glockenspiel on 06/25/2002 11:45:27
Go to Top of Page

Glockenspiel
Yak Posting Veteran

50 Posts

Posted - 2002-06-25 : 12:16:10
OK; here's a cleaned up version of the code:

DECLARE @multiplier TINYINT
--Remove comment for the multiplier that suits your # of CPUs
--SET @multiplier = 32 -- This is for a 1-way machine
--SET @multiplier = 16 -- This is for a 2-way machine
--SET @multiplier = 8 -- This is for a 4-way machine
--SET @multiplier = 4 -- This is for a 8-way machine

SELECT
@@cpu_busy / 60000.0 * @multiplier AS minutes_cpu_busy,
@@io_busy / 60000.0 * @multiplier AS minutes_io_busy,
@@idle / 60000.0 * @multiplier AS minutes_idle,
(@@cpu_busy + @@io_busy + @@idle) / 60000.0 * @multiplier AS minutes_since_restart,
DATEADD(ms, -1 * @multiplier * (@@cpu_busy + @@io_busy + @@idle), GETDATE()) AS computed_startup_time



Edited by - Glockenspiel on 06/25/2002 12:18:48
Go to Top of Page

Page47
Master Smack Fu Yak Hacker

2878 Posts

Posted - 2002-06-25 : 12:41:26
I like...

so should I assume it that the multipler for a three way would be 12?

<O>

Edited by - Page47 on 06/25/2002 12:42:43
Go to Top of Page

efelito
Constraint Violating Yak Guru

478 Posts

Posted - 2002-06-25 : 12:42:35
From BOL:
quote:
Returns the time in milliseconds (based on the resolution of the system timer) that the CPU has spent doing work since Microsoft® SQL Server™ was last started


The number you are dividing by depends on your processor speed. So to get the cpu minutes busy and have it work across all of your servers you would need to do something like this...

declare @mspertick int
select @mspertick = convert(int, @@timeticks / 1000.0)
SELECT ((@@cpu_busy*@mspertick)/1000.0)/60 AS minutes_cpu_busy


Jeff Banschbach
Consultant, MCDBA


Edited by - efelito on 06/25/2002 12:43:59
Go to Top of Page

Glockenspiel
Yak Posting Veteran

50 Posts

Posted - 2002-06-25 : 12:58:11
I think BOL is bollocks -- their timeticks method (as per the previous poster's query) yields consistently illogical results. The only thing that seems to work is using a multiplier that is purely number-of-CPUs based and not clock-speed-based. I've tested this on a variety of machines with a variety of clock speeds and numbers of CPUs and I seem to be getting consistently correct and logical results.

Edited by - Glockenspiel on 06/25/2002 12:59:07
Go to Top of Page

graz
Chief SQLTeam Crack Dealer

4149 Posts

Posted - 2002-06-25 : 13:12:03
Here's a little script I wrote to show an ISP who'se using most of their resources over a given range of time:

declare @Seconds int

set nocount on

If @Seconds IS NULL
Set @Seconds = 10


CREATE TABLE [#sysprocess] (
[spid] [smallint] NOT NULL ,
[blocked] [smallint] NOT NULL ,
[cpu] [int] NOT NULL ,
[physical_io] [bigint] NOT NULL ,
[memusage] [int] NOT NULL ,
[open_tran] [smallint] NOT NULL ,
[status] [nchar] (30) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
[cmd] [nchar] (16) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
[loginame] [nchar] (128) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
[tStamp] [datetime] NULL
CONSTRAINT [DF__hold_sysp__tStam__5AAF56EE] DEFAULT (getdate())
)

Declare @i int

set @i = 0


While @i <= @Seconds
begin

insert #sysprocess (spid, blocked, cpu,
physical_io, memusage, open_tran, status, cmd, loginame )
select spid, blocked, cpu, physical_io,
memusage, open_tran, status, cmd, loginame
from master..sysprocesses

set @i = @i + 1

waitfor delay '00:00:01'
end


declare @total_ms numeric(8,2)
declare @StartTime datetime, @StopTime datetime
declare @msg varchar(1000)
-- by loginame
Select @StartTime = min(tstamp) ,
@StopTime = max(tstamp) ,
@total_ms = datediff(ms, min(tstamp), max(tstamp))
from dbo.hold_sysprocess

Print 'Started at: ' + convert(varchar, @StartTime)
Print ' '
Print 'Duration (ms): ' + convert(varchar, @total_ms)
Print ' '
--Print 'Results by loginame:'
Print '---------- CPU Users -----------'
Print ' '
select top 10 left(loginame, 20) as loginame,
sum(CPU) as [CPU (ms)],
convert(numeric(5,0), convert( numeric(8,2), sum(CPU)) / @total_ms * 100 )
as CPU_Pct,
sum(IO) as IO,
Sum(Mem) as Mem_pages,
Sum(Mem) * 8 as Mem_KB

From (select spid, loginame, CPU = max_cpu - min_cpu,
IO = max_io - min_io,
Mem = max_memusage
from (select spid, loginame, min(cpu) as min_cpu, max(cpu) as max_cpu,
min(physical_io) as min_io, Max(physical_io) as max_io,
max(memusage) as max_memusage
from #sysprocess
group by spid, loginame) as a ) as b
group by loginame
Order by 2 desc, 5 desc

Print ' '
Print '---------- Memory Users -----------'
Print ' '
select top 10 left(loginame, 20) as loginame, sum(CPU) as [CPU (ms)],
convert(numeric(5,0), convert( numeric(8,2), sum(CPU)) / @total_ms * 100 )
as CPU_Pct,
sum(IO) as IO,
Sum(Mem) as Mem_pages,
Sum(Mem) * 8 as Mem_KB

From (select spid, loginame, CPU = max_cpu - min_cpu,
IO = max_io - min_io,
Mem = max_memusage
from (select spid, loginame, min(cpu) as min_cpu, max(cpu) as max_cpu,
min(physical_io) as min_io, Max(physical_io) as max_io,
max(memusage) as max_memusage
from #sysprocess
group by spid, loginame) as a ) as b
group by loginame
Order by 5 desc, 2 desc

Print ' '
Print '---------- IO Users -----------'
Print ' '
select top 10 left(loginame, 20) as loginame, sum(CPU) as [CPU (ms)],
convert(numeric(5,0), convert( numeric(8,2), sum(CPU)) / @total_ms * 100 )
as CPU_Pct,
sum(IO) as IO,
Sum(Mem) as Mem_pages,
Sum(Mem) * 8 as Mem_KB

From (select spid, loginame, CPU = max_cpu - min_cpu,
IO = max_io - min_io,
Mem = max_memusage
from (select spid, loginame, min(cpu) as min_cpu, max(cpu) as max_cpu,
min(physical_io) as min_io, Max(physical_io) as max_io,
max(memusage) as max_memusage
from #sysprocess
group by spid, loginame) as a ) as b
group by loginame
having Sum(IO) <> 0
Order by 4 desc, 2 desc

drop table #sysprocess
set nocount off


It's not especially pretty but it seems to work.

===============================================
Creating tomorrow's legacy systems today.
One crisis at a time.
Go to Top of Page

MichaelP
Jedi Yak

2489 Posts

Posted - 2002-06-25 : 13:40:37
Page47, as soon as you have 3 CPU's running in a box, let me know.

I'm pretty sure you can only have them in multiples of 2
2
4
6
8

Michael

--------------------
<Yoda>Use the Search page you must.
Go to Top of Page

Page47
Master Smack Fu Yak Hacker

2878 Posts

Posted - 2002-06-25 : 13:52:40
Will you buy me a if I am right?

Come on over and we'll crack the case on this mofo....

It's a three way, it reports 3 processors, perfmon lets me choose from three processors, it was speced for three processors.....

EDIT:
xp_cmdshell 'set number_of_processors'

output
--------------------------------------
NUMBER_OF_PROCESSORS=3

(1 row(s) affected)

<O>

Edited by - Page47 on 06/25/2002 14:03:15
Go to Top of Page

setbasedisthetruepath
Used SQL Salesman

992 Posts

Posted - 2002-06-25 : 14:05:58
quote:

Page47, as soon as you have 3 CPU's running in a box, let me know.

I'm pretty sure you can only have them in multiples of 2
2
4
6
8



To the best of my knowledge, you could only have them in powers of 2, as in 2,4,8,16 ...

But, Page's proof is in ...

Jonathan Boott, MCDBA
Go to Top of Page

MichaelP
Jedi Yak

2489 Posts

Posted - 2002-06-25 : 14:59:14
Page, you actually have a 3-way box? Wow!

Who makes it? What model is it? I've GOT to see thing!

The only way I can think of getting 3 cpu's in one PC is with those Industrial PC's that use single board computers, but even still I don't think you can have all three working in concert.

Michael


--------------------
<Yoda>Use the Search page you must.
Go to Top of Page

Page47
Master Smack Fu Yak Hacker

2878 Posts

Posted - 2002-06-25 : 15:20:51
Hold onto your shorts . . . its made by a little, unknown company called Compaq . . . a 6500 I believe . . .

In all fairness, I've never seen one either. But sure enuff, here I am at a client site with a three-way 6500 production database server....sql seems to use all three, with the affinity_mask set to 0.



<O>
Go to Top of Page

Glockenspiel
Yak Posting Veteran

50 Posts

Posted - 2002-06-25 : 17:28:40
quote:
Here's a little script I wrote to show an ISP who'se using most of their resources over a given range of time:


Thanks graz, I'll give this a whirl.

Go to Top of Page

ThreePea
Yak Posting Veteran

83 Posts

Posted - 2002-12-27 : 11:42:05
quote:

DECLARE @multiplier TINYINT
--Remove comment for the multiplier that suits your # of CPUs
--SET @multiplier = 32 -- This is for a 1-way machine
--SET @multiplier = 16 -- This is for a 2-way machine
--SET @multiplier = 8 -- This is for a 4-way machine
--SET @multiplier = 4 -- This is for a 8-way machine



Ok. This sounds great, but something was fishy when I attempted to use this code for some performance metrics on our development machine. So I wrote the following script which should return the correct multiplier:


DECLARE @uptime_seconds1 INT
DECLARE @uptime_seconds2 INT

SELECT
@uptime_seconds1 = DATEDIFF(s, crdate, GETDATE())
FROM master..sysdatabases WHERE NAME = 'tempdb'

SET
@uptime_seconds2 = (@@CPU_BUSY + @@IO_BUSY + @@IDLE) / 1000

SELECT
(@uptime_seconds1 * 1.0) / @uptime_seconds2 AS 'Multiplier'


When I run this on our 1-processor development machine I get 32, right on the money. However, when I run this on our 4-proc production machine, I get 18.8! No matter how many different methods I use to calculate the multiplier on production I keep getting 18.8. Now that I know what the multiplier is I can use it, but it doesn't make any sense. Any ideas?


==================================================
Tolerance is the last virtue of an immoral society. -- G.K. Chesterton
Go to Top of Page

ValterBorges
Master Smack Fu Yak Hacker

1429 Posts

Posted - 2002-12-27 : 19:26:48
quote:

DECLARE @multiplier TINYINT
--Remove comment for the multiplier that suits your # of CPUs
--SET @multiplier = 32 -- This is for a 1-way machine
--SET @multiplier = 16 -- This is for a 2-way machine
--SET @multiplier = 8 -- This is for a 4-way machine
--SET @multiplier = 4 -- This is for a 8-way machine



Looks to me like the multiplier is 32.0/#Processors.
You could use

EXEC master.dbo.xp_msver 'ProcessorCount'

to find out the number of Processors.




Edited by - ValterBorges on 12/27/2002 19:33:56
Go to Top of Page

robvolk
Most Valuable Yak

15732 Posts

Posted - 2003-01-01 : 13:49:05
Just out of curiosity, have you tried using sp_monitor?

Go to Top of Page

ThreePea
Yak Posting Veteran

83 Posts

Posted - 2003-01-02 : 12:23:57
quote:
EXEC master.dbo.xp_msver 'ProcessorCount'
to find out the number of Processors.
ValterBorges, thanks for the tip on xp_msver, now my script is generic.

quote:
Just out of curiosity, have you tried using sp_monitor?

Rob, I just tried using sp_monitor. I get an error:

Server: Msg 8115, Level 16, State 2, Procedure sp_monitor, Line 94
Arithmetic overflow error converting expression to data type int.

Unfortunately, I don't have the time to debug sp_monitor right now and see what is overflowing.

However, my actual question is that I have one machine that does not seem to adhere to the (32 / #processors) formula for the correct multiplier. The script I posted a couple posts back in this thread uses reverse calculations to show the true multiplier on the machine where it is run.

When I run this on my 1-processor machine, it returns 32. Check. When I run it on my 2-processor machine, it returns 16. Check. However, when I run it on my 4-processor machine (which is our production server), I get 17.2. Huh? A few days ago the same script was returning 18.8. I'm just trying to see if anyone knows why this machine doesn't follow the formula. Obviously, I am missing something (actually, many things, but we won't go into that here ).

Thanks.


==================================================
Tolerance is the last virtue of an immoral society. -- G.K. Chesterton
Go to Top of Page
   

- Advertisement -