N S

Novick Software Management • Design • Programming • Training • Consulting

   

 

 

SQL Server T-SQL User-Defined Function of the Week

How Much of the CPU is SQL Server Using?

Volume 1 Number 39    August 12, 2003

Visit the T-SQL UDF of the Week at:
http://www.NovickSoftware.com/UdfOfWeek/UDFofWeek.htm

Check out the UDF Frequently Asked Questions at:
http://www.novicksoftware.com/UdfOfWeek/UDF_FAQ.htm

To ask a UDF related question or to contribute a UDF,
send e-mail to udf@NovickSoftware.com

Sign up for this newsletter at:
http://www.novicksoftware.com/UdfOfWeek/UDFofWeekSignup.htm
In an article published last week on www.DatabaseJournal.com 
I wrote about using system statistical functions, sp_monitor, 
and fn_virtualfilestats for accumulating Input/Output statistics
about a SQL Server instance.  You'll find the article at:
http://databasejournal.com/article.php/2244381

One of the tricks about @@CPU_BUSY, @@IDLE, and @@IO_BUSY is that
the Books Online appears to be incorrect when it states that
these functions return a time in milliseconds.  It appears that
they return a time in timer ticks instead.  

To convert from timer ticks to seconds, it's necessary to multiply
by the value of another system statistical function @@TIMETICK,
which returns the number of microseconds (millionths of a second)
in a tick.

The formula for CPU seconds is:

   @@CPU_BUSY * @@TIMETICK / 1000000
   
On Intel 386, 486, and Pentium based systems, a timer tick is 
1/32nd of a second or 31250 microseconds.  I suspect that it's 
different on Itanium, Alpha, and XScale processors.

This week's UDF, udf_Instance_CPU_BUSY_Percent shows the percent
of CPU time used by SQL Server since it was started.  To compute
it we first have to know the number of seconds since SQL Server
started.  The function udf_SQL_StartDT provides the date time
that the server started.  The function is available in Issue 11,
which you'll find at this URL:
http://www.novicksoftware.com/UDFofWeek/Vol1/T-SQL-UDF-Volume-1-Number-11-udf_SQL_StartDT.htm

udf_Instance_CPU_BUSY_Percent relies on three non-deterministic built-in
functions: getdate, @@CPU_BUSY, and @@TIMETICK.  Normally, a
non-deterministic function can't be used in a UDF.  There's a 
way around it that you can read about in Issue 2. It involves
creating a view that invokes the function.  You'll need one
view for each function.  The one for getdate is in Issue 2, which
you can get at this URL:
http://www.novicksoftware.com/UDFofWeek/Vol1/T-SQL-UDF-Volume-1-Number-2-udf_DT_CurrTime.htm
The script to create the other two views follows:
/------- Start copying below this line -------------------------\
SET QUOTED_IDENTIFIER ON 
SET ANSI_NULLS ON 
GO

CREATE  VIEW dbo.Function_Assist_TIMETICKS

    WITH SCHEMABINDING
/*
* A view to return one row, with one column, the current 
* value of the built-in function @@TIMETICKS.  This view 
* allows a UDF to bypass the restriction on access to 
* the non-deterministic @@TIMETICKS function.
*
* Example:
DECLARE @dtVar int
select @dtVAr = [TIMETICKS] from Function_Assist_TIMETICKS
**********************************************************/

AS 
    SELECT @@TIMETICKS as [TIMETICKS]
GO

GRANT SELECT on dbo.Function_Assist_TIMETICKS to PUBLIC
GO


CREATE  VIEW dbo.Function_Assist_CPU_BUSY

    WITH SCHEMABINDING
/*
* A view to return one row, with one column, the current 
* value of the built-in function @@CPU_BUSY.  This view 
* allows a UDF to bypass the restriction on access to 
* the non-deterministic @@CPU_BUSY function.
*
* Example:
DECLARE @dtVar int
select @dtVAr = [CPU_BUSY] from Function_Assist_CPU_BUSY
**********************************************************/

AS 
    SELECT @@CPU_BUSY as [CPU_BUSY]

GO

GRANT SELECT on dbo.Function_Assist_CPU_BUSY to PUBLIC
GO
\-------Stop copying above this line ---------------------------/


Once the views are defined, the function can be created. Here's 
the CREATE FUNCTION script:
/------- Start copying below this line -------------------------\
SET QUOTED_IDENTIFIER ON 
SET ANSI_NULLS ON 
GO


CREATE  FUNCTION dbo.udf_Instance_CPU_BUSY_Percent (

)   RETURNS numeric (18,2) -- Percentage of the 
    -- NO SCHEMABINDING 
/* 
* Computes the percentage of time that the CPU has been busy with
* SQL Server work since the SQL Server Instance was started.
*
* Example:
select dbo.udf_Instance_CPU_BUSY_Percent()
* 
* History:
* When          Who     Description
* ------------- ------- -----------------------------------------
* 2003-08-04    ASN     Initial Coding
*
* © Copyright 2003 Andrew Novick http://www.NovickSoftware.com
* You may use this function in any of your SQL Server databases
* including databases that you sell, so long as they contain 
* other unrelated database objects. You may not publish this 
* UDF either in print or electronically.
* Published as the T-SQL UDF of the Week Vol 1 #39  8/12/03
http://www.NovickSoftware.com/UDFofWeek/UDFofWeek.htm
****************************************************************/
AS BEGIN

DECLARE @Percent_CPU_BUSY numeric (18,2)
      , @SecondsFromStart int -- sec since the instance started

SELECT @SecondsFromStart = DATEDIFF (s
                                   , dbo.udf_SQL_StartDT()
                                   , [getdate]
                                    )
    FROM Function_Assist_Getdate

SELECT @Percent_CPU_Busy = CAST([cpu_busy] as float) 
                         * [timeticks] 
                         / 10000.0
                         / CAST(@SecondsFromStart as float)
    FROM FUNCTION_Assist_CPU_BUSY
       CROSS JOIN FUNCTION_Assist_TimeTicks

RETURN @Percent_CPU_BUSY

END

GO

GRANT EXEC on [dbo].[udf_Instance_CPU_BUSY_Percent] to PUBLIC
GO
\-------Stop copying above this line ---------------------------/

Now that the function is ready, let's try it out:
/------- Start copying below this line -------------------------\
select dbo.udf_Instance_CPU_BUSY_Percent() as [CPU_BUSY_Percent]
GO
\-------Stop copying above this line ---------------------------/
(Results)
CPU_BUSY_Percent     
-------------------- 
                9.05 

That looks like a reasonable number for CPU percentage to me. On 
a server that's dedicated to SQL Server, I don't worry about the
number until it gets over 70 percent.  Of course, the percentage
here is an average since the instance started.  What's more 
important is peak usage.  To get a quick look at that, use 
sp_monitor.  There's more about how it works in the article.


+--------------------------------------------------------------+
Do you have a great UDF that you'd like to share?  Or maybe you
have a T-SQL problem that you think could be solved by a UDF
but you don't know how? Send them to:

UDF@NovickSoftware.com 

and they might be published in this newsletter.  I try and 
respond to every request that I get.  

Thanks,  
Andrew Novick
+--------------------------------------------------------------+


RSS as HTML

Personal Blog

 
New Tips:

Loading SQL Profiler trace (.trc) files with fn_trace_gettrace

Upcoming
Presentations:

Big Data:
Working with Terabytes
in SQL Server

July 9 '08


Full Schedule