Showing posts with label SQL. Show all posts
Showing posts with label SQL. Show all posts

Tuesday, February 8

Formatting SQL Code for Blogs

Up until recently, all the SQL code on this blog looked awful: completely lacking in formatting and unreadable (though still useful!). It looked like this:

SELECT
*
FROM
Ow.My.Eyes.Hurt

Then I discovered The Simple-Talk Code Prettifier.

You pop your formatted SQL code in (copied out of SSMS or Visual Studio), choose the style of HTML (forums in my case), whether to correct indenting and lenth of tabs etc., and voila: html code is produced which results in something real pretty like the below:

SELECT
        
*
  
FROM
        
Oh.That.Be.Nice
        


Thanks to the HOBT (Aaron Alton) for blogging about this tool better and sooner than I.

Wednesday, February 18

Database Performance Monitoring on the Cheap

The system views are (to many) hidden gems in SQL. One in particular I'd like to address today is [sys].[dm_os_performance_counters], available in SQL2005 (and I assume 2008).

A quick SELECT * FROM [sys].[dm_os_performance_counters] will show you all that's available; a whole range of performance counters that you'd often go to Perfmon to check out.

The advantage of having this all so simply queryable from SQL is that we can start recording this every x minutes/hours, and start charting it out, and get some ideas about some of the weaknesses of our DBs, when they're under load etc.

First we need somewhere to store the data:


   ----------------------------------------------------------------------------------------
   --
   -- Create a schema
   --
   ----------------------------------------------------------------------------------------
CREATE SCHEMA [Monitoring];
  

   ----------------------------------------------------------------------------------------
   --
   -- Create a table for the stats to live in
   --
   ----------------------------------------------------------------------------------------
CREATE TABLE [Monitoring].[PerformanceCounters](
            
[DateTimeID] [bigint] NOT NULL,
            
[DateTime] [datetime] NOT NULL,
            
[object_name] [nvarchar](128) NOT NULL,
            
[counter_name] [nvarchar](128) NOT NULL,
            
[instance_name] [nvarchar](128) NULL,
            
[cntr_value] [bigint] NULL,
            
[cntr_type] [int] NULL,
            
CONSTRAINT [pkPerformanceCounters] PRIMARY KEY CLUSTERED
      
(
              
[DateTimeID] ASC,
              
[counter_name] ASC
      
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [PRIMARY]
  
) ON [PRIMARY]
        



I've used a DateTimeID field as I don't like using Datetimes as part of primary keys, and also they can be useful in any Analysis Services you might want to do down the road.

Now for a proc to record some counters (feel free to pick and choose which counters you think are appropriate, and please let me know if you've any suggestions):


   ----------------------------------------------------------------------------------------
   --
   -- Create a procedure which will query the DMVs and store the results for reporting
   --
   ----------------------------------------------------------------------------------------
CREATE PROCEDURE [Monitoring].[sPerformanceCountersInsert]
        
AS
   BEGIN
   INSERT INTO
              
[Monitoring].[PerformanceCounters]
      
SELECT
            
CAST(DATEPART(YEAR, GETDATE()) AS bigint)*100000000+
            
DATEPART(MONTH, GETDATE())*1000000+
            
DATEPART(DAY, GETDATE())*10000+
            
DATEPART(hour, GETDATE())*100+
            
DATEPART(minute, GETDATE()),
            
GETDATE(),
            
[dm_os_performance_counters].[object_name],
            
[dm_os_performance_counters].[counter_name],
            
[dm_os_performance_counters].[instance_name],
            
[dm_os_performance_counters].[cntr_value],
            
[dm_os_performance_counters].[cntr_type]
      
FROM
            
[TheDBYouWantToMonitor].[sys].[dm_os_performance_counters]
      
WHERE
      
(
              
OBJECT_NAME = 'SQLServer:Buffer Manager'
            
AND (
                  
counter_name = 'Page life expectancy'
        
)
      )
         OR (
              
OBJECT_NAME = 'SQLServer:General Statistics'
            
AND (
                  
counter_name = 'User Connections'
              
OR counter_name = 'Processes blocked'
        
)
      )
         OR (
              
OBJECT_NAME = 'SQLServer:Databases'
            
AND instance_name = 'TheDBYouWantToMonitor'
            
AND (
                  
counter_name = 'Transactions/sec'
        
)
      )
         OR (
              
OBJECT_NAME = 'SQLServer:Access Methods'
            
AND (
                  
counter_name = 'Full Scans/sec'
              
OR counter_name = 'Range Scans/sec'
              
OR counter_name = 'Index Searches/sec'
              
OR counter_name = 'Page Splits/sec'
              
OR counter_name = 'Table Lock Escalations/sec'
        
)
      )
         OR (
              
OBJECT_NAME = 'SQLServer:SQL Statistics'
            
AND counter_name = 'SQL Re-Compilations/sec'
      
)
         OR (
              
OBJECT_NAME = 'SQLServer:Memory Manager'
            
AND counter_name = 'Memory Grants Outstanding'
      
)
         OR (
              
OBJECT_NAME = 'SQLServer:Transactions'
            
AND counter_name = 'Transactions'
      
)
  
END


This is all pretty DB centric stuff, it's unfortunate that more server level stats aren't available with this method, such as memory and disk usage.

Now we just need to set up a SQL Server Agent job to fire off that job every x minutes/hours. That'll depend on how busy your DB is, on my main prod DB I've got this guy running every 5 minutes, and a similar proc recording Data and Log file sizes on a daily basis.

Once you've got enough historical data, it's a simple matter to query:

CREATE PROCEDURE [Monitoring].[sPerformanceCountersSelectByDateRange]
  
@FormerDate DATETIME,
  
@LatterDate DATETIME
         AS
   BEGIN
   SELECT
            
[DateTimeID]
            
,[DateTime]
            
,[object_name]
            
,[counter_name]
            
,[instance_name]
            
,[cntr_value]
            
,[cntr_type]
      
FROM
            
[Monitoring].[PerformanceCounters]
      
WHERE
            
[DateTime] BETWEEN @FormerDate
        
AND @LatterDate
  
END



I'm hooking this proc up into a Reporting Services report at the moment, charting each counter seperately. It's quite interesting to see the shapes of the charts, and spurring me into understanding more about what each one really means. It's great stuff to show to mgt as well, giving them a bit of a look into the black box that is their SQL Server.

Friday, December 5

Ongoing Education for the Terminally Lazy/Busy

Reading msdn articles and whitepapers and textbooks blows goats as far as I'm concerned. I'm interested for about 5 minutes, max.

However I’ve been learning a lot about SQL (as well as plenty of other things) since I got myself set up in the RSS world, subscribing to blog and site feeds in Google Reader.

Maybe I’m preaching to the choir on this blog entry about RSS, but amongst the DB people I know very few seem that savvy about efficient net usage.

These sites below publish regularly, and when you subscribe to them in Google Reader, you can get a heap of relevant information into your unread “inbox” instead of regularly checking sites to see if anything’s updated.

If you’ve got a gmail account, you’re crazy not to start using Reader, and it works great on mobile phones cutting down bandwidth hungry sites into nice little readable chunks.

So, below, are my favourite sites/blogs which update regularly with useful SQL goodies. At least check them out, and if you’re not already in the RSS feed world, get yourself subscribed to these guys in Google Reader and you’ll be picking up more info than ever in a digestible fashion.

Blogs:
http://www.brentozar.com/
http://statisticsio.com/
http://itknowledgeexchange.techtarget.com/sql-server/
http://blog.sqlauthority.com/

For sites, check out:
http://sqlserverpedia.com/wiki and http://www.sqlservercentral.com/