Tuesday, 2 August 2016

Blocking - Brute force approach

-- Find requests being blocked
SELECT *
FROM sys.dm_exec_requests
WHERE blocking_session_id <> 0;
GO

-- Generate SQL to kill everything blocking session id 85
SELECT distinct 'kill ' +
    CONVERT(varchar,blocking_session_id )
FROM sys.dm_os_waiting_tasks
WHERE
   session_id = 85;

 

Saturday, 2 July 2016

SSIS 2016 - Command Line Deployment for Projects


Project based deployment can be automated from the command line.

I create a batch file for this and put PAUSE at the end so that I can review the output before the window closes!

isdeploymentwizard.exe /Silent /ModelType:Project /SourcePath:"E:\Codebase\SSIS\SSIS Solutions\My Solution\ProductionPackages\bin\Development\My Solution.ispac" /DestinationServer:"LIVESERVER.DOMAIN.LOCAL" /DestinationPath:"/SSISDB/Folder/My Solution"

pause

Tuesday, 28 June 2016

CTE to create a sequence of numbers

DECLARE @start INT, @end INT, @increment INT
SELECT @start=0, @end=100000000, @increment = 50000
 
;WITH NumberList ( Number ) AS
(
    SELECT @start as Number
        UNION ALL
    SELECT Number + @increment
        FROM NumberList
        WHERE Number < @end
)
 
SELECT Number FROM NumberList OPTION (MAXRECURSION 0)

Tuesday, 12 January 2016

SQL Page Compression - Rollout script.

An update to my original script to apply PAGE Compression to all objects
Obviously, you need to weigh up the benefits of doing so first.

This version includes the rowcounts but orders the statements so you compress the table before it's associated indexes.
SELECT distinct rows,SCHEMA_NAME(schema_id) as SchemaName, Name AS TableName,'Table' AS ObjectType,1 AS ExecutionOrder,'ALTER TABLE [' + SCHEMA_NAME(schema_id) + '].[' + NAME + '] REBUILD PARTITION = ALL WITH (MAXDOP=1,ONLINE=ON,DATA_COMPRESSION = PAGE);' AS [SQLCommand]
FROM sys.objects o
inner join sys.partitions p
on o.object_id = p.object_id
where o.TYPE = 'u'
and p.data_compression = 0
UNION ALL
SELECT distinct rows,SCHEMA_NAME(schema_id) as SchemaName, Name AS TableName,'Index' AS ObjectType,2 AS ExecutionOrder,'ALTER INDEX ALL ON [' + SCHEMA_NAME(schema_id) + '].[' + NAME + '] REBUILD PARTITION = ALL WITH (MAXDOP=1,ONLINE=ON,DATA_COMPRESSION = PAGE);' AS [SQLCommand] 
FROM sys.objects o
inner join sys.partitions p
on o.object_id = p.object_id
where o.TYPE = 'u'
and p.data_compression = 0
order by SCHEMA_NAME(schema_id),Name,ExecutionOrder

Thursday, 28 May 2015

Investigating a (suddenly) slow running query...

Some Questions / lines of enquiry ...

What else was going on on the server at that time?

  • Is blocking occuring?
  • Is another process monopolising resources (memory, cpu, i/o)

What has changed?

  •  Any code changes
  •  Any configuration change
  •  Any change in data volume (influx of new data)

Is all maintenance happening? (it won't take long to check)

  • Are statistics up to date
  • How is index fragmentation
  • Are backups occurring (remember full backups control log fie growth)
Can the query be run manually?
- Look at Execution plan

Is it a stored procedure?
- Look at Execution plan for parameter differences (parameter sniffing)

Parameter Sniffing

A short reminder, again to get this fresh in my mind....

Parameter Sniffing is when a previously compiled execution plan is reused with different parameter values. This is by design and is generally good as we are saving time by not compiling a new plan. Occasionally though it can lead to suboptimal choices when the procedure is run again, with new parameter values.

If a procedure returns only 1 row with 1 parameter value and 1 million with a different parameter value then the optimal plans for retrieving those rows may be very different.
Here the retrieval of a million rows wold be done using the plan generated for 1 row.

2 ways around parameter sniffing are forcing a recompile (WITH RECOMPILE) in the procedure definition or using the OPTIMIZE FOR query hint.

Simple Talk : Parameter Sniffing
Brent Ozar : Parameter Sniffing
MSDN : Parameter Sniffing & Workarounds


Plan Cache Pollution

They say if you can't explain something easily, you don't understand it well enough. For that reason, I'm revisiting some things I take for granted.

The Plan Cache is where SQL Server stores exection plans.

If queries are not parameterized, the plan cache fills with lots of similar queries of hard coded values.

SELECT mycolumns FROM mytable WHERE myid = 1
SELECT mycolumns FROM mytable WHERE myid = 2
SELECT mycolumns FROM mytable WHERE myid = 3
SELECT mycolumns FROM mytable WHERE myid = 4

If queries are parameterized (or parameterization is forced on at a database level) then 1 entry will be in the cache instead.

SELECT mycolumns FROM mytable WHERE myid = n

Correctly parameterized queries will prevent wasting cpu (generating plans) & memory (storing them). Allowing the cache to fill with simiar plans in this way is Plan Cache Pollution.

You can examine the plan cache with the sys.dm_exec_cached_plans DMO.

Links -
Tamarick Hill : sys.dm_exec_cached_plans
Klaus Aschenbrenner : Plan Cache Pollution