Wednesday, March 21, 2018

Performance Tuning - SQL Server


Performance Tuning

1.    DMV - sys.dm_os_wait_stats

2.    DMV - sys.dm_os_performance_counters

3.    DMV - sys.dm_io_virtual_file_stats

4.    DMV - sys.dm_io_pending_io_requests

5.    DMV - sys.dm_exec_query_memory_grants

6.    DMV - sys.dm_exec_sql_text

7.    DMV - sys.dm_exec_query_resource_semaphores

8.    DMV - sys.dm_os_wait_stats

9.    DMV - sys.dm_os_schedulers

10. Extended Proc Sp_who5

11. Performance Monitor - PerfMon



1.DMV - sys.dm_os_wait_stats

ABOUT

Ø  DMV - that helps us to understand wait stats is sys.dm_os_wait_stats.

Ø  This DMV gives us all the information that we need to know regarding wait stats

Ø  Specific types of wait times during query execution can indicate bottlenecks or stall points within the query. Similarly, high wait times, or wait counts server wide can indicate bottlenecks or hot spots in interaction query interactions within the server instance


COLUMN DETAILS

wait_type – this is the name of the wait type. There can be three different kinds of wait types – resource, queue and external.
waiting_tasks_count – this incremental counter is a good indication of frequent the wait is happening. If this number is very high, it is good indication for us to investigate that particular wait type. It is quite possible that the wait time is considerably low, but the frequency of the wait is much high.
wait_time_ms – this is total wait accumulated for any type of wait. This is the total wait time and includes singal_wait_time_ms.
max_wait_time_ms – this indicates the maximum wait type ever occurred for that particular wait type. Using this, one can estimate the intensity of the wait type in past. Again, it is not necessary that this max wait time will occur every time; so do not over invest yourself here.
signal_wait_time_ms – this is the wait time when thread is marked as runnable and it gets to the running state. If the runnable queue is very long, you will find that this wait time becomes high.


REFERENCE QUERY

Select * from sys.dm_os_wait_stats order by wait_time_ms desc

With Percentage
WITH Waits AS
 (
 SELECT 
   wait_type, 
   wait_time_ms / 1000. AS wait_time_s,
   100. * wait_time_ms / SUM(wait_time_ms) OVER() AS pct,
   ROW_NUMBER() OVER(ORDER BY wait_time_ms DESC) AS rn
 FROM sys.dm_os_wait_stats
 WHERE wait_type 
   NOT IN
     ('CLR_SEMAPHORE', 'LAZYWRITER_SLEEP', 'RESOURCE_QUEUE',
   'SLEEP_TASK', 'SLEEP_SYSTEMTASK', 'SQLTRACE_BUFFER_FLUSH', 'WAITFOR',
   'CLR_AUTO_EVENT', 'CLR_MANUAL_EVENT')
   ) -- filter out additional irrelevant waits
   
SELECT W1.wait_type,
 CAST(W1.wait_time_s AS DECIMAL(12, 2)) AS wait_time_s,
 CAST(W1.pct AS DECIMAL(12, 2)) AS pct,
 CAST(SUM(W2.pct) AS DECIMAL(12, 2)) AS running_pct
FROM Waits AS W1
 INNER JOIN Waits AS W2 ON W2.rn <= W1.rn
GROUP BY W1.rn, 
 W1.wait_type, 
 W1.wait_time_s, 
 W1.pct
HAVING SUM(W2.pct) - W1.pct < 95; -- percentage threshold;

2.DMV - sys.dm_os_performance_counters

Reference

ABOUT

DMV that returns one row for each SQL Server performance counter. It’s useful for obtaining information about current performance counter values, you can collect counter information that you would receive from PerfMon for the various SQL Server counters
COLUMN DETAILS
·         Cache Hit Ratio – I ignore this value, but I still monitor it. I will, ideally, never be the only DBA on a team again, and everyone seems to think this value is cool.
·         Page Life Exp – My favorite! When you read a page from disk into memory how many seconds will it stay there? Just don’t use the outdated “300” rule or your disks will catch on fire!!!

·         Page Lookups/Sec – How many pages are read from memory.
·         Page Reads/Sec – How many pages are read from disk.
·         Page Writes/Sec – How many pages are written to disk.
·         Lazy Writes/sec – How many pages are written to disk outside of a checkpoint due to memory pressure.
·         Batch Requests/sec – How busy is the server?
·         Trans/sec – How busy is the server?
·         Total Server Memory – How much memory SQL Server is currently using. Typically ramps up to Target value and PLE is low as it ramps up since new pages are in memory dropping the average.
·         Target Server Memory – How much memory SQL Server is allowed to use. Should be the same as the max memory setting, but memory pressure can cause this to decrease.
·         Memory Grants Pending – How many processes aren’t able to get enough memory to run. Should be 0, always 0, if not then find out why.
·         Deadlocks – How many deadlocks are we getting. Most apps handle deadlocks gracefully, but they still lose time doing it. If this number starts going up, start looking into it.
·         SQL Compilations/sec – This is a hidden performance killer! Some queries can’t be cached so they’re compiled every time they’re run. I’ve seen this with a query being run once a second and a big server was running slower than my laptop. It’s normal for things to compile throughout the day, it’s not normal for this number to be 10x higher than before that last upgrade.
·         SQL Re-Compilations/sec – Same goes here. The counters aren’t that much different.

REFERENCE QUERY
-- it must be > 95 always
SELECT object_name, counter_name, cntr_value
FROM sys.dm_os_performance_counters
WHERE [object_name] LIKE '%Buffer Manager%'
AND [counter_name] = 'Buffer cache hit ratio'

3.DMV - sys.dm_io_virtual_file_stats

Reference


ABOUT

Returns I/O statistics for data and log files. This dynamic management view replaces the fn_virtualfilestats function.
The sys.dm_io_virtual_file_stats DMV will show an IO Stall when any wait occurs to access a physical data file.
Virtual file stats are a great starting point when you want to understand I/O performance for a SQL Server instance.
The DMV contains cumulative I/O information for each database file, but the data resets on instance restart

Need

SQL Server constantly brings database pages in and out of the buffer pool. This generates substantial I/O traffic. Similarly, the log records need to be flushed to the disk before a transaction can be declared committed. And finally, SQL Server uses TempDB for various purposes such as to store intermediate results, to sort, to keep row versions and so on. So a good I/O subsystem is critical to the performance of SQL Server

Perfmon Counter

Set in PerfMon that captures the Physical Disk counters Avg. Disk Sec/Read and Avg. Disk Sec/Read for all disks that host database files.
Storage latency can exist for a variety of reasons, such as:
  • SQL Server has to read too much data as a result of inefficient query plans or missing indexes
  • Too little memory is allocated to the instance and the same data is read from disk over and over because it cannot stay in memory
  • Implicit conversions cause index or table scans
  • Queries perform SELECT * when not all columns are required
  • Forwarded record problems in heaps cause additional I/O
  • Low page densities from index fragmentation, page splits, or incorrect fill factor settings cause additional I/O

COLUMN DETAILS
sample_ms
Number of milliseconds since the computer was started. This column can be used to compare different outputs from this function.
The data type is 
int for SQL Server 2008 through SQL Server 2014
num_of_reads
Number of reads issued on the file.
num_of_bytes_read
Total number of bytes read on this file.
io_stall_read_ms
Total time, in milliseconds, that the users waited for reads issued on the file.
num_of_writes
Number of writes made on this file.
num_of_bytes_written
Total number of bytes written to the file.
io_stall_write_ms
Total time, in milliseconds, that users waited for writes to be completed on the file.
io_stall
Total time, in milliseconds, that users waited for I/O to be completed on the file.
size_on_disk_bytes
Number of bytes used on the disk for this file. For sparse files, this number is the actual number of bytes on the disk that are used for database snapshots.

REFERENCE QUERY
select DB_NAME(database_id) As DB,* from sys.dm_io_virtual_file_stats(null,null)
Order By num_of_writes Desc


SELECT a.io_stall, a.io_stall_read_ms, a.io_stall_write_ms, a.num_of_reads, 
a.num_of_writes, 
--a.sample_ms, a.num_of_bytes_read, a.num_of_bytes_written, a.io_stall_write_ms, 
( ( a.size_on_disk_bytes / 1024 ) / 1024.0 ) AS size_on_disk_mb, 
db_name(a.database_id) AS dbname, 
b.name, a.
file_id
db_file_type = 
CASE 
                   
WHEN a.file_id = 2 THEN 'Log' 
                   ELSE 'Data' 
                   END
UPPER(SUBSTRING(b.physical_name, 1, 2)) AS disk_location 
FROM sys.dm_io_virtual_file_stats (NULL, NULL) a 
JOIN sys.master_files b ON a.file_id = b.file_id 
AND a.database_id = b.database_id 
ORDER BY a.io_stall DESC
Other Perfmon Counters
You can use the following performance counters to identify I/O bottlenecks. Note, these AVG values tend to be skewed (to the low side) if you have an infrequent collection interval. For example, it is hard to tell the nature of an I/O spike with 60-second snapshots. Also, you should not rely on one counter to determine a bottleneck; look for multiple counters to cross check the validity of your findings.
  • Physical Disk Object: Avg. Disk Queue Length represents the average number of physical read and write requests that were queued on the selected physical disk during the sampling period. If your I/O system is overloaded, more read/write operations will be waiting. If your disk queue length frequently exceeds a value of 2 during peak usage of SQL Server, then you might have an I/O bottleneck.
  • Avg. Disk Sec/Read is the average time, in seconds, of a read of data from the disk. Any number:
    • Less than 10 ms - very good
    • Between 10 - 20 ms - okay
    • Between 20 - 50 ms - slow, needs attention
    • Greater than 50 ms - Serious I/O bottleneck
  • Avg. Disk Sec/Write is the average time, in seconds, of a write of data to the disk. Please refer to the guideline in the previous bullet.
  • Physical Disk: %Disk Time is the percentage of elapsed time that the selected disk drive was busy servicing read or write requests. A general guideline is that if this value is greater than 50 percent, it represents an I/O bottleneck.
  • Avg. Disk Reads/Sec is the rate of read operations on the disk. You need to make sure that this number is less than 85 percent of the disk capacity. The disk access time increases exponentially beyond 85 percent capacity.
  • Avg. Disk Writes/Sec is the rate of write operations on the disk. Make sure that this number is less than 85 percent of the disk capacity. The disk access time increases exponentially beyond 85 percent capacity.
When using above counters, you may need to adjust the values for RAID configurations using the following formulas.
  • Raid 0 -- I/Os per disk = (reads + writes) / number of disks
  • Raid 1 -- I/Os per disk = [reads + (2 * writes)] / 2
  • Raid 5 -- I/Os per disk = [reads + (4 * writes)] / number of disks
  • Raid 10 -- I/Os per disk = [reads + (2 * writes)] / number of disks
For example, you have a RAID-1 system with two physical disks with the following values of the counters.
  • Disk Reads/sec -  80
  • Disk Writes/sec - 70
  • Avg. Disk Queue Length - 5
In that case, you are encountering (80 + (2 * 70))/2 = 110 I/Os per disk and your disk queue length = 5/2 = 2.5 which indicates a border line I/O bottleneck."

4.DMV - sys. dm_io_pending_io_requests

Reference

ABOUT

Returns a row for each pending I/O request in SQL Server.
COLUMN DETAILS
REFERENCE QUERY

select * from sys.dm_io_pending_io_requests cross apply sys.dm_io_virtual_file_stats(null,null)

/* The query below can be used to determine if pending IO is causing work to be queued on the scheduler. */
SELECT f.database_id, f.[file_id], DB_NAME(f.database_id) AS database_name, f.name AS logical_file_name, f.type_desc,
CAST (CASE
-- Handle UNC paths (e.g. '\\fileserver\DBs\readonly_dw.ndf')
WHEN LEFT (LTRIM (f.physical_name), 2) = '\\'
THEN LEFT (LTRIM (f.physical_name),CHARINDEX('\',LTRIM(f.physical_name),CHARINDEX('\',LTRIM(f.physical_name), 3) + 1) - 1)
-- Handle local paths (e.g. 'C:\Program Files\...\master.mdf')
WHEN CHARINDEX('\', LTRIM(f.physical_name), 3) > 0
THEN UPPER(LEFT(LTRIM(f.physical_name), CHARINDEX ('\', LTRIM(f.physical_name), 3) - 1))
ELSE f.physical_name
END AS NVARCHAR(255)) AS logical_disk,
fs.io_stall/1000/60 AS io_stall_min,
fs.io_stall_read_ms/1000/60 AS io_stall_read_min,
fs.io_stall_write_ms/1000/60 AS io_stall_write_min,
(fs.io_stall_read_ms / (1.0 + fs.num_of_reads)) AS avg_read_latency_ms,
(fs.io_stall_write_ms / (1.0 + fs.num_of_writes)) AS avg_write_latency_ms,
((fs.io_stall_read_ms/1000/60)*100)/(CASE WHEN fs.io_stall/1000/60 = 0 THEN 1 ELSE fs.io_stall/1000/60 END) AS io_stall_read_pct,
((fs.io_stall_write_ms/1000/60)*100)/(CASE WHEN fs.io_stall/1000/60 = 0 THEN 1 ELSE fs.io_stall/1000/60 END) AS io_stall_write_pct,
ABS((fs.sample_ms/1000)/60/60) AS 'sample_HH',
((fs.io_stall/1000/60)*100)/(ABS((fs.sample_ms/1000)/60))AS 'io_stall_pct_of_overall_sample',
PIO.io_pending_ms_ticks,
PIO.scheduler_address,
os.scheduler_id,
os.pending_disk_io_count,
os.work_queue_count
FROM sys.dm_io_pending_io_requests AS PIO
INNER JOIN sys.dm_io_virtual_file_stats (NULL,NULL) AS fs
ON fs.file_handle = PIO.io_handle
INNER JOIN sys.master_files AS f
ON fs.database_id = f.database_id AND fs.[file_id] = f.[file_id] INNER JOIN sys.dm_os_schedulers AS os
ON PIO.scheduler_address = os.scheduler_address

5.DMV - sys.dm_exec_query_memory_grants

Reference


ABOUT

Returns information about the queries that have acquired a memory grant or that still require a memory grant to execute. Queries that do not have to wait on a memory grant will not appear in this view.
DMV
COLUMN DETAILS


requested_memory_kb
Total requested amount of memory in kilobytes.
granted_memory_kb
Total amount of memory actually granted in kilobytes. Can be NULL if the memory is not granted yet. For a typical situation, this value should be the same as requested_memory_kb. For index creation, the server may allow additional on-demand memory beyond initially granted memory.
required_memory_kb
Minimum memory required to run this query in kilobytes. requested_memory_kb is the same or larger than this amount.
used_memory_kb
Physical memory used at this moment in kilobytes.

REFERENCE QUERY
select session_idrequested_memory_kbgranted_memory_kbideal_memory_kb
from sys.dm_exec_query_memory_grants

SELECT mg.granted_memory_kb, mg.session_id, t.text, qp.query_plan
FROM sys.dm_exec_query_memory_grants AS mg
CROSS APPLY sys.dm_exec_sql_text(mg.sql_handle) AS t
CROSS APPLY sys.dm_exec_query_plan(mg.plan_handle) AS qp
ORDER BY 1 DESC OPTION (MAXDOP 1)

6.DMV - sys.dm_exec_sql_text

Reference


ABOUT

Returns the text of the SQL batch that is identified by the specified sql_handle.
REFERENCE QUERY

Select  * from sys.dm_exec_requests cross apply sys.dm_exec_sql_text(sql_handle)

7.DMV - sys.dm_exec_query_resource_semaphores

Reference


ABOUT

Returns the information about the current query-resource semaphore status in SQL Server. sys.dm_exec_query_resource_semaphores provides general query-execution memory status and allows you to determine whether the system can access enough memory
COLUMN DETAILS
total_memory_kb
Memory held by the resource semaphore in kilobytes. If the system is under memory pressure or if forced minimum memory is granted frequently, this value can be larger than the target_memory_kb or max_target_memory_kbvalues. Total memory is a sum of available and granted memory.
available_memory_kb
Memory available for a new grant in kilobytes.
granted_memory_kb
Total granted memory in kilobytes.
used_memory_kb
Physically used part of granted memory in kilobytes.
grantee_count
Number of active queries that have their grants satisfied.
waiter_count
Number of queries waiting for grants to be satisfied.

REFERENCE QUERY
select * from sys.dm_exec_query_resource_semaphores

8.DMV - sys.dm_os_wait_stats

Reference

ABOUT

Returns information about all the waits encountered by threads that executed. You can use this aggregated view to diagnose performance issue Since SQL server started
COLUMN DETAILS
Column name
Description
wait_type
Name of the wait type.
waiting_tasks_count
Number of waits on this wait type. This counter is incremented at the start of each wait.
wait_time_ms
Total wait time for this wait type in milliseconds. This time is inclusive of signal_wait_time_ms.
max_wait_time_ms
Maximum wait time on this wait type.
signal_wait_time_ms
Difference between the time that the waiting thread was signaled and when it started running

REFERENCE QUERY
An excellent query for this purpose is from Paul S. Randal blog, which will give the cumulative wait statistic for the most important wait statistic types

Select * from sys.dm_os_wait_stats order by wait_time_ms desc

SELECT *
FROM sys.dm_os_wait_stats WHERE waiting_tasks_count > 0
ORDER BY wait_time_ms DESC
GO

SELECT  [wait_type] ,
        [wait_time_ms] ,
        DATEADD(SS, -[wait_time_ms] / 1000, GETDATE()) AS "Date/TimeCleared" ,
        CASE WHEN [wait_time_ms] < 1000
             THEN CAST([wait_time_ms] AS VARCHAR(15)) + ' ms'
             WHEN [wait_time_ms] BETWEEN 1000 AND 60000
             THEN CAST(( [wait_time_ms] / 1000 ) AS VARCHAR(15)) + ' seconds'
             WHEN [wait_time_ms] BETWEEN 60001 AND 3600000
             THEN CAST(( [wait_time_ms] / 60000 ) AS VARCHAR(15)) + ' minutes'
             WHEN [wait_time_ms] BETWEEN 3600001 AND 86400000
             THEN CAST(( [wait_time_ms] / 3600000 ) AS VARCHAR(15)) + ' hours'
             WHEN [wait_time_ms] > 86400000
             THEN CAST(( [wait_time_ms] / 86400000 ) AS VARCHAR(15)) + ' days'
        END AS "TimeSinceCleared"
FROM    [sys].[dm_os_wait_stats]
--WHERE   [wait_type] = 'SQLTRACE_INCREMENTAL_FLUSH_SLEEP';
Order By [wait_time_ms] desc

9.DMV - sys.dm_os_schedulers

Reference


ABOUT

Occurs when a task voluntarily yields the scheduler for other tasks to execute. During this wait the task is waiting for its quantum to be renewed.
SOS_SCHEDULER_YIELD is a fairly common wait type and occurs when there is CPU pressure. SQL Server runs multiple threads and tries to allow all threads to run without problems. However, if all the threads are busy on each scheduler and can't let other threads run, it will yield itself for another thread, which in turn creates the SOS_SCHEDULER_YIELD wait type.
WITH Waits AS
(
SELECT
wait_type,
wait_time_ms / 1000. AS wait_time_s,
100. * wait_time_ms / SUM(wait_time_ms) OVER() AS pct,
ROW_NUMBER() OVER(ORDER BY wait_time_ms DESC) AS rn
FROM sys.dm_os_wait_stats
WHERE wait_type
NOT IN
('CLR_SEMAPHORE', 'LAZYWRITER_SLEEP', 'RESOURCE_QUEUE',
'SLEEP_TASK', 'SLEEP_SYSTEMTASK', 'SQLTRACE_BUFFER_FLUSH', 'WAITFOR',
'CLR_AUTO_EVENT', 'CLR_MANUAL_EVENT')
) -- filter out additional irrelevant waits
SELECT W1.wait_type,
CAST(W1.wait_time_s AS DECIMAL(12, 2)) AS wait_time_s,
CAST(W1.pct AS DECIMAL(12, 2)) AS pct,
CAST(SUM(W2.pct) AS DECIMAL(12, 2)) AS running_pct
FROM Waits AS W1
INNER JOIN Waits AS W2 ON W2.rn <= W1.rn
GROUP BY W1.rn,
W1.wait_type,
W1.wait_time_s,
W1.pct
HAVING SUM(W2.pct) - W1.pct < 95; -- percentage threshold;

COLUMN DETAILS
This DMV has several columns including number or workers, active tasks, and the status of each scheduler, etc., which can help troubleshoot certain problems, but the most important column is the one used for measuring queued tasks, the runnable_tasks_count column. This column displays the count of tasks yielding to other tasks resulting in a SOS_SCHEDULER_YIELD wait type. If this column is frequently greater than 0 then CPU pressure may be present and blocking may occur.
REFERENCE QUERY
-- Get Avg task count and Avg runnable task count
SELECT AVG(current_tasks_count) AS [Avg Task Count], 
AVG(runnable_tasks_count) AS [Avg Runnable Task Count]
FROM sys.dm_os_schedulers
WHERE scheduler_id < 255
AND [status] = 'VISIBLE ONLINE';
This query will help detect blocking and can help detect and confirm CPU pressure. High, sustained values for current_tasks_count usually indicates you are seeing lots of blocking. I have also seen it be a secondary indicator of I/O pressure. High, sustained values for runnable_tasks_count is usually a very good indicator of CPU pressure.  By “high, sustained values”, I mean anything above about 10-20 for most systems.
-- Is NUMA enabled
SELECT 
  CASE COUNT(DISTINCT parent_node_id)
     WHEN 1 
         THEN 'NUMA disabled' 
         ELSE 'NUMA enabled'
  END
FROM sys.dm_os_schedulers
WHERE parent_node_id <> 32;
The second query will tell you whether Non-uniform memory access (NUMA) is enabled on your SQL Server instance. AMD based servers have supported hardware based NUMA for several years, while Intel based Xeon servers, have added hardware based NUMA with the Xeon 5500, 5600, and 7500 series. There is also software based NUMA.

10.Extended Proc Sp_who5

ABOUT

Extended SP to monitor the sql server running processes.
REFERENCE QUERY
Create proc [dbo].[SP_Who5]
As
SELECT SPID = er.session_id
    , ot.Threads
    , RunningThreads = coalesce(rsp.RunningThreads,0)
    , Pct_Comp = er.percent_complete
    , Est_Comp_Time = CASE er.estimated_completion_time WHEN 0 THEN NULL ELSE dateadd(ms, er.estimated_completion_time, getdate()) END
    , er.status
    , er.command
    , database_name = sd.name
    , BlockedBy = wt.blocking_session_id
    , HeadBlocker = coalesce(hb5.session_id, hb4.session_id, hb3.session_id, hb2.session_id, hb1.session_id)
    , wait_type = coalesce(CASE er.wait_type WHEN 'CXPACKET' THEN 'CXPACKET - ' + sp.lastwaittype1 ELSE sp.lastwaittype1 END, lower(er.last_wait_type)) --Lowercase denotes it's not currently waiting, also noted by a wait time of 0.
    , Wait_Time_Sec = Cast(er.wait_time/1000.0 as DEC(20,3))
    , er.wait_resource
    , Duration_Sec = Cast(DATEDIFF(s, er.start_time, GETDATE()) as DEC(20,0))
    , CPU_Sec = Cast(er.cpu_time/1000.0 as DEC(20,3))
    , Reads_K = Cast(er.reads/1000.0 as DEC(20,3))
    , Writes_K = Cast(er.writes/1000.0 as DEC(20,3))
    , [Statement] = SUBSTRING (st.text, er.statement_start_offset/2,
        abs(CASE WHEN er.statement_end_offset = -1
               THEN LEN(CONVERT(NVARCHAR(MAX), st.text)) * 2
            ELSE er.statement_end_offset END - er.statement_start_offset)/2)
    , st.text as Query
    , es.login_time
    , es.host_name
    , program_name = CASE LEFT(es.program_name, 29)
                    WHEN 'SQLAgent - TSQL JobStep (Job '
                        THEN 'SQLAgent Job: ' + (SELECT name FROM msdb..sysjobs sj WHERE substring(es.program_name,32,32)=(substring(sys.fn_varbintohexstr(sj.job_id),3,100))) + ' - ' + SUBSTRING(es.program_name, 67, len(es.program_name)-67)
                    ELSE es.program_name
                    END 
    , es.client_interface_name
    , es.login_name
    , es.status
    , es.total_scheduled_time
    , es.total_elapsed_time
    , er.start_time
    , es.last_request_start_time
    , es.last_request_end_time
    , er.database_id 
    --, qp.query_plan
FROM sys.dm_exec_requests er
    INNER JOIN sys.dm_exec_Sessions es on er.session_id=es.session_id
    LEFT JOIN sys.databases sd on er.database_id=sd.database_id
    INNER JOIN (SELECT session_id, count(1) Threads FROM sys.dm_os_tasks GROUP BY session_id) ot on er.session_id=ot.session_id
    LEFT JOIN (SELECT spid, LastWaitType1 = MIN(lastwaittype), LastWaitType2 = MAX(lastwaittype) FROM sysprocesses sp WHERE waittime > 0 AND lastwaittype <> 'cxpacket' GROUP BY spid) sp ON er.session_id = sp.spid
    LEFT JOIN (SELECT spid, RunningThreads = COUNT(1) FROM sysprocesses sp WHERE waittime = 0 GROUP BY spid) rsp ON er.session_id = rsp.spid
    LEFT JOIN (SELECT session_id, max(blocking_session_id) blocking_session_id FROM sys.dm_os_waiting_tasks wt WHERE wt.blocking_session_id <> wt.session_id GROUP BY session_id) wt ON er.session_id = wt.session_id
    LEFT JOIN (SELECT session_id, max(blocking_session_id) blocking_session_id FROM sys.dm_os_waiting_tasks wt GROUP BY session_id) hb1 ON wt.blocking_session_id = hb1.session_id
    LEFT JOIN (SELECT session_id, max(blocking_session_id) blocking_session_id FROM sys.dm_os_waiting_tasks wt GROUP BY session_id) hb2 ON hb1.blocking_session_id = hb2.session_id
    LEFT JOIN (SELECT session_id, max(blocking_session_id) blocking_session_id FROM sys.dm_os_waiting_tasks wt GROUP BY session_id) hb3 ON hb2.blocking_session_id = hb3.session_id
    LEFT JOIN (SELECT session_id, max(blocking_session_id) blocking_session_id FROM sys.dm_os_waiting_tasks wt GROUP BY session_id) hb4 ON hb3.blocking_session_id = hb4.session_id
    LEFT JOIN (SELECT session_id, max(blocking_session_id) blocking_session_id FROM sys.dm_os_waiting_tasks wt GROUP BY session_id) hb5 ON hb4.blocking_session_id = hb5.session_id
    CROSS APPLY sys.dm_exec_sql_text(sql_handle) AS st 
    --CROSS APPLY sys.dm_exec_query_plan(er.plan_handle) qp
WHERE er.session_id <> @@SPID
    --AND es.host_name like '%%'
    --AND er.session_id = 2702
ORDER BY er.percent_complete DESC, er.cpu_time DESC, er.session_id


GO


11.Performance Monitor - PerfMon

Reference


ABOUT

The Microsoft Windows Performance Monitor is a tool that administrators can use to examine how programs running on their computers affect the computer's performance.

Understanding PerfMon Counters and their Results

Performance Counter
Information Provided
Expected Value
% Disk Read Time
Amount of time your disks are being read
Less than 15-20%
% Disk Time
Amount of time your disks are in use
Less than 15-20%
% Disk Write Time
Amount of time your disks are being written to
Less than 15-20%
% Idle Time
Amount of time your disks are idle or not performing any action
Over 85%
Current Disk Queue Length
Amount of time the Operating System must wait to access the disks
Less than 1**
Disk Reads/sec
Overall rate of read operations on the disk (Can be used to determine IOP’s to evaluate hardware needs and as a benchmark for hardware upgrades.)
Less than 70-80%*
Disk Writes/sec
Overall rate of write operations on the disk (Can be used to determine IOP’s to evaluate hardware needs and as a benchmark for hardware upgrades.)
Less than 70-80%*
Split IO/sec
Overall rate at which the operating system divides I/O requests to the disk into multiple requests.
On single disk volumes, a high Split IO/sec value may indicate a badly fragmented drive. Defraying may increase performance.

For detail, refer the above link.

Configure Perfmon Counter


Important Counters


·         PhysicalDisk/%idle time - should not be less than ~%60
·         PhysicalDisk/Avg. Disk sec/Read should not be higher than ~20ms
·         PhysicalDisk/Avg. Disk sec/Write should not be higher than ~20ms
·         PhysicalDisk/Current disk queue length. should not be higher than 2
·         Memory\Available Mbytes, minimum 10% of memory should be free and available
·         \Memory\Pages/sec should not be higher than 1000
·         Network Interface(*)\Bytes Total/sec
o    Less than 40% of the interface consumed = Healthy
o    41%-64% of the interface consumed = Monitor or Caution
o    65-100% of the interface consumed = Critical, performance will be adversely affected
·         Network Interface(*)\Output Queue Length
o    0 = Healthy
o    1-2 = Monitor or Caution
o    Greater than 2 = Critical, performance will be adversely affected
·         Hyper-V Hypervisor Logical Processor(_Total)\% Total Run Time
o    Less than 60% consumed = Healthy
o    60% - 89% consumed = Monitor or Caution
o    90% - 100% consumed = Critical, performance will be adversely affected
·         Paging File\%Usage should not be higher than %10


No comments:

Post a Comment