DMVsinSQLServer -- 备

时间:2022-09-09 11:12:29
/*******************************************************************************************************

                    SQL SERVER 2005 - Tell me your secrets!

********************************************************************************************************

    Description: Report on the current performance health status of a SQL Server 2005 server using non-instrusive methods.

    Purpose: Identify areas where the database server as a whole can be improved, using data collected
by SQL Server itself. Many of these items apply to the database server as a whole, rather
than specific queries. Author: Ian Stirk (Ian_Stirk@yahoo.com). Date: June 2007. Notes: This collection of SQL inspects various DMVs, this information can be used to highlight
what areas of the SQL Server sever can be improved. The following items are reported on: 1. Causes of the server waits
2. Databases using the most IO
3. Count of missing indexes, by database
4. Most important missing indexes
5. Unused Indexes
6. Most costly indexes (high maintenance)
7. Most used indexes
8. Most fragmented indexes
9. Most costly queries, by average IO
10. Most costly queries, by average CPU
11. Most costly CLR queries, by average CLR time
12. Most executed queries
13. Queries suffering most from blocking
14. Queries with the lowest plan reuse ******************************************************************************************************** PRE-REQUISITE
1. Best to have as much DMV data as possible (When last rebooted? Want daily? weekly, monthly, quarterly results).
2. Output HSR to Grid? Text? File? Table? Reporting Services? If set results to text, get the actual sprocs in output.
3. Decide if want to put results in a database? Later analysis, historical comparisons, impact of month-end, quarter etc.
4. Decide if want to run the defrag code, can be expensive.
5. Decide if want to iterate over all databases for a specific aspect (e.g. average IO). FOLLOW-UP (After running this routine's SQL)
1. Investigative work, use dba_SearchDB/dba_SearchDBServer for analysis.
2. Demonstrate/measure the improvement: Find underlying queries, apply change, run stats IO ON, see execuation plan.
3. SQL Server Best Practices Analyzer. INTRUSIVE INSPECTION (Follow-up and corollary to this work)
1. Trace typical workload (day, monthend? etc)
2. Reduce recorded queries to query signatures (Ben-Gan's method)
3. Calculate the total duration for similar query patterns
4. Tune the most important query patterns in DTA, then apply recommended indexes/stats. *********************************************************************************************************/ -- Do not lock anything, and do not get held up by any locks.
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED SELECT 'Identify what is causing the waits.' AS [Step01];
/************************************************************************************/
/* STEP01. */
/* Purpose: Identify what is causing the waits. */
/* Notes: 1. */
/************************************************************************************/
SELECT TOP 10
[Wait type] = wait_type,
[Wait time (s)] = wait_time_ms / 1000,
[% waiting] = CONVERT(DECIMAL(12,2), wait_time_ms * 100.0 / SUM(wait_time_ms) OVER())
FROM sys.dm_os_wait_stats
WHERE wait_type NOT LIKE '%SLEEP%'
--AND wait_type NOT LIKE 'CLR_%'
ORDER BY wait_time_ms DESC; SELECT 'Identify what databases are reading the most logical pages.' AS [Step02a];
/************************************************************************************/
/* STEP02a. */
/* Purpose: Identify what databases are reading the most logical pages. */
/* Notes : 1. This should highlight the databases to target for best improvement. */
/* 2. Watch out for tempDB, a high value is suggestive. */
/************************************************************************************/
-- Total reads by DB
SELECT TOP 10
[Total Reads] = SUM(total_logical_reads)
,[Execution count] = SUM(qs.execution_count)
,DatabaseName = DB_NAME(qt.dbid)
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) as qt
GROUP BY DB_NAME(qt.dbid)
ORDER BY [Total Reads] DESC; SELECT 'Identify what databases are writing the most logical pages.' AS [Step02b];
/************************************************************************************/
/* STEP02b. */
/* Purpose: Identify what databases are writing the most logical pages. */
/* Notes : 1. This should highlight the databases to target for best improvement. */
/* 2. Watch out for tempDB, a high value is suggestive. */
/************************************************************************************/
-- Total Writes by DB
SELECT TOP 10
[Total Writes] = SUM(total_logical_writes)
,[Execution count] = SUM(qs.execution_count)
,DatabaseName = DB_NAME(qt.dbid)
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) as qt
GROUP BY DB_NAME(qt.dbid)
ORDER BY [Total Writes] DESC; SELECT 'Count of missing indexes, by databases.' AS [Step03];
/************************************************************************** ******************/
/* STEP03. */
/* Purpose: Identify the number of missing (or incomplete indexes), across ALL databases. */
/* Notes : 1. This should highlight the databases to target for best improvement. */
/*********************************************************************************************/
SELECT
DatabaseName = DB_NAME(database_id)
,[Number Indexes Missing] = count(*)
FROM sys.dm_db_missing_index_details
GROUP BY DB_NAME(database_id)
ORDER BY 2 DESC; SELECT 'Identify the missing indexes (TOP 10), across ALL databases.' AS [Step04];
/****************************************************************************************************/
/* STEP04. */
/* Purpose: Identify the missing (or incomplete indexes) (TOP 20), for ALL databases. */
/* Notes : 1. Could combine above with number of reads/writes a DB has since reboot, but this takes */
/* into account how often index could have been used, and estimates a 'realcost' */
/****************************************************************************************************/
SELECT TOP 10
[Total Cost] = ROUND(avg_total_user_cost * avg_user_impact * (user_seeks + user_scans),0)
, avg_user_impact -- Query cost would reduce by this amount, on average.
, TableName = statement
, [EqualityUsage] = equality_columns
, [InequalityUsage] = inequality_columns
, [Include Cloumns] = included_columns
FROM sys.dm_db_missing_index_groups g
INNER JOIN sys.dm_db_missing_index_group_stats s ON s.group_handle = g.index_group_handle
INNER JOIN sys.dm_db_missing_index_details d ON d.index_handle = g.index_handle
ORDER BY [Total Cost] DESC; SELECT 'Identify which indexes are not being used, across ALL databases.' AS [Step05];
/*******************************************************************************************************/
/* STEP05. */
/* Purpose: Identify which indexes are not being used, for a given database. */
/* Notes: 1. These will have a deterimental impact on any updates/deletions. */
/* Remove if possible (can see the updates in user_updates and system_updates fields) */
/* 2. Systems means DBCC commands, DDL commands, or update statistics - so can typically ignore. */
/* 3. The template below uses the sp_MSForEachDB, this is because joining on sys.databases */
/* gives incorrect results (due to sys.indexes taking into account the current database only). */
/********************************************************************************************************/
-- Create required table structure only.
-- Note: this SQL must be the same as in the Database loop given in following step.
SELECT TOP 1
DatabaseName = DB_NAME()
,TableName = OBJECT_NAME(s.[object_id])
,IndexName = i.name
,user_updates
,system_updates
-- Useful fields below:
--, *
INTO #TempUnusedIndexes
FROM sys.dm_db_index_usage_stats s
INNER JOIN sys.indexes i ON s.[object_id] = i.[object_id]
AND s.index_id = i.index_id
WHERE s.database_id = DB_ID()
AND OBJECTPROPERTY(s.[object_id], 'IsMsShipped') = 0
AND user_seeks = 0
AND user_scans = 0
AND user_lookups = 0
-- Below may not be needed, they tend to reflect creation of stats, backups etc...
-- AND system_seeks = 0
-- AND system_scans = 0
-- AND system_lookups = 0
AND s.[object_id] = -999 -- Dummy value, just to get table structure.
; -- Loop around all the databases on the server.
EXEC sp_MSForEachDB 'USE [?];
-- Table already exists.
INSERT INTO #TempUnusedIndexes
SELECT TOP 10
DatabaseName = DB_NAME()
,TableName = OBJECT_NAME(s.[object_id])
,IndexName = i.name
,user_updates
,system_updates
-- Useful fields below:
--, *
FROM sys.dm_db_index_usage_stats s
INNER JOIN sys.indexes i ON s.[object_id] = i.[object_id]
AND s.index_id = i.index_id
WHERE s.database_id = DB_ID()
AND OBJECTPROPERTY(s.[object_id], ''IsMsShipped'') = 0
AND user_seeks = 0
AND user_scans = 0
AND user_lookups = 0
AND i.name IS NOT NULL -- I.e. Ignore HEAP indexes.
-- Below may not be needed, they tend to reflect creation of stats, backups etc...
-- AND system_seeks = 0
-- AND system_scans = 0
-- AND system_lookups = 0
ORDER BY user_updates DESC
;
' -- Select records.
SELECT TOP 10 * FROM #TempUnusedIndexes ORDER BY [user_updates] DESC
-- Tidy up.
DROP TABLE #TempUnusedIndexes SELECT 'Identify which indexes are the most high maintenance (TOP 10), across ALL databases.' AS [Step06];
/********************************************************************************************************/
/* STEP06. */
/* Purpose: Identify which indexes are the most high maintenance (TOP 10), for a given database. */
/* Notes: 1. These indexes are updated the most, may want to review if the are necessary. */
/* 2. Another version shows writes per read. */
/* 3. Systems means DBCC commands, DDL commands, or update statistics - so can typically ignore. */
/* 4. The template below uses the sp_MSForEachDB, this is because joining on sys.databases */
/* gives incorrect results (due to sys.indexes taking into account the current database only). */
/********************************************************************************************************/
-- Create required table structure only.
-- Note: this SQL must be the same as in the Database loop given in following step.
SELECT TOP 1
[Maintenance cost] = (user_updates + system_updates)
,[Retrieval usage] = (user_seeks + user_scans + user_lookups)
,DatabaseName = DB_NAME()
,TableName = OBJECT_NAME(s.[object_id])
,IndexName = i.name
-- Useful fields below:
-- ,user_updates
-- ,system_updates
-- ,user_seeks
-- ,user_scans
-- ,user_lookups
-- ,system_seeks
-- ,system_scans
-- ,system_lookups
-- Useful fields below:
-- ,*
INTO #TempMaintenanceCost
FROM sys.dm_db_index_usage_stats s
INNER JOIN sys.indexes i ON s.[object_id] = i.[object_id]
AND s.index_id = i.index_id
WHERE s.database_id = DB_ID()
AND OBJECTPROPERTY(s.[object_id], 'IsMsShipped') = 0
AND (user_updates + system_updates) > 0 -- Only report on active rows.
AND s.[object_id] = -999 -- Dummy value, just to get table structure.
; -- Loop around all the databases on the server.
EXEC sp_MSForEachDB 'USE [?];
-- Table already exists.
INSERT INTO #TempMaintenanceCost
SELECT TOP 10
[Maintenance cost] = (user_updates + system_updates)
,[Retrieval usage] = (user_seeks + user_scans + user_lookups)
,DatabaseName = DB_NAME()
,TableName = OBJECT_NAME(s.[object_id])
,IndexName = i.name
-- Useful fields below:
-- ,user_updates
-- ,system_updates
-- ,user_seeks
-- ,user_scans
-- ,user_lookups
-- ,system_seeks
-- ,system_scans
-- ,system_lookups
-- Useful fields below:
-- ,*
FROM sys.dm_db_index_usage_stats s
INNER JOIN sys.indexes i ON s.[object_id] = i.[object_id]
AND s.index_id = i.index_id
WHERE s.database_id = DB_ID()
AND i.name IS NOT NULL -- I.e. Ignore HEAP indexes.
AND OBJECTPROPERTY(s.[object_id], ''IsMsShipped'') = 0
AND (user_updates + system_updates) > 0 -- Only report on active rows.
ORDER BY [Maintenance cost] DESC
;
' -- Select records.
SELECT TOP 10 * FROM #TempMaintenanceCost ORDER BY [Maintenance cost] DESC
-- Tidy up.
DROP TABLE #TempMaintenanceCost SELECT 'Identify which indexes are the most often used (TOP 10), across ALL databases.' AS [Step07];
/********************************************************************************************************/
/* STEP07. */
/* Purpose: Identify which indexes are the most used (TOP 10), for a given database. */
/* Notes: 1. These indexes are updated the most, may want to review if the are necessary. */
/* 2. Systems means DBCC commands, DDL commands, or update statistics - so can typically ignore. */
/* 3. Ensure Statistics are up-to-date for these. */
/* 4. The template below uses the sp_MSForEachDB, this is because joining on sys.databases */
/* gives incorrect results (due to sys.indexes taking into account the current database only). */
/********************************************************************************************************/ -- Create required table structure only.
-- Note: this SQL must be the same as in the Database loop given in following step.
SELECT TOP 1
[Usage] = (user_seeks + user_scans + user_lookups)
,DatabaseName = DB_NAME()
,TableName = OBJECT_NAME(s.[object_id])
,IndexName = i.name
-- Useful fields below:
-- ,user_updates
-- ,system_updates
-- ,user_seeks
-- ,user_scans
-- ,user_lookups
-- ,system_seeks
-- ,system_scans
-- ,system_lookups
-- Useful fields below:
--, *
INTO #TempUsage
FROM sys.dm_db_index_usage_stats s
INNER JOIN sys.indexes i ON s.[object_id] = i.[object_id]
AND s.index_id = i.index_id
WHERE s.database_id = DB_ID()
AND OBJECTPROPERTY(s.[object_id], 'IsMsShipped') = 0
AND (user_seeks + user_scans + user_lookups) > 0 -- Only report on active rows.
AND s.[object_id] = -999 -- Dummy value, just to get table structure.
; -- Loop around all the databases on the server.
EXEC sp_MSForEachDB 'USE [?];
-- Table already exists.
INSERT INTO #TempUsage
SELECT TOP 10
[Usage] = (user_seeks + user_scans + user_lookups)
,DatabaseName = DB_NAME()
,TableName = OBJECT_NAME(s.[object_id])
,IndexName = i.name
-- Useful fields below:
-- ,user_updates
-- ,system_updates
-- ,user_seeks
-- ,user_scans
-- ,user_lookups
-- ,system_seeks
-- ,system_scans
-- ,system_lookups
-- Useful fields below:
--, *
FROM sys.dm_db_index_usage_stats s
INNER JOIN sys.indexes i ON s.[object_id] = i.[object_id]
AND s.index_id = i.index_id
WHERE s.database_id = DB_ID()
AND i.name IS NOT NULL -- I.e. Ignore HEAP indexes.
AND OBJECTPROPERTY(s.[object_id], ''IsMsShipped'') = 0
AND (user_seeks + user_scans + user_lookups) > 0 -- Only report on active rows.
ORDER BY [Usage] DESC
;
' -- Select records.
SELECT TOP 10 * FROM #TempUsage ORDER BY [Usage] DESC
-- Tidy up.
DROP TABLE #TempUsage SELECT 'Identify which indexes are the most logically fragmented (TOP 10), across ALL databases.' AS [Step08];
/********************************************************************************************/
/* STEP08. */
/* Purpose: Identify which indexes are the most fragmented (TOP 10), for a given database. */
/* Notes: 1. Defragmentation increases IO. */
/********************************************************************************************/
---- Create required table structure only.
---- Note: this SQL must be the same as in the Database loop given in following step.
--SELECT TOP 1
-- DatbaseName = DB_NAME()
-- ,TableName = OBJECT_NAME(s.[object_id])
-- ,IndexName = i.name
-- ,[Fragmentation %] = ROUND(avg_fragmentation_in_percent,2)
-- -- Useful fields below:
-- --, *
--INTO #TempFragmentation
--FROM sys.dm_db_index_physical_stats(db_id(),null, null, null, null) s
--INNER JOIN sys.indexes i ON s.[object_id] = i.[object_id]
-- AND s.index_id = i.index_id
--WHERE s.[object_id] = -999 -- Dummy value, just to get table structure.
--;
--
---- Loop around all the databases on the server.
--EXEC sp_MSForEachDB 'USE [?];
---- Table already exists.
--INSERT INTO #TempFragmentation
--SELECT TOP 10
-- DatbaseName = DB_NAME()
-- ,TableName = OBJECT_NAME(s.[object_id])
-- ,IndexName = i.name
-- ,[Fragmentation %] = ROUND(avg_fragmentation_in_percent,2)
-- -- Useful fields below:
-- --, *
--FROM sys.dm_db_index_physical_stats(db_id(),null, null, null, null) s
--INNER JOIN sys.indexes i ON s.[object_id] = i.[object_id]
-- AND s.index_id = i.index_id
--WHERE s.database_id = DB_ID()
-- AND i.name IS NOT NULL -- I.e. Ignore HEAP indexes.
-- AND OBJECTPROPERTY(s.[object_id], ''IsMsShipped'') = 0
--ORDER BY [Fragmentation %] DESC
--;
--'
--
---- Select records.
--SELECT TOP 10 * FROM #TempFragmentation ORDER BY [Fragmentation %] DESC
---- Tidy up.
--DROP TABLE #TempFragmentation SELECT 'Identify which (cached plan) queries are the most costly by average IO (TOP 10), across ALL databases.' AS [Step09];
/****************************************************************************************************/
/* STEP09. */
/* Purpose: Identify which queries are the most costly by IO (TOP 10), across ALL databases. */
/* Notes: 1. This could be areas that need optimisation, maybe they crosstab with missing indexes? */
/* 2. Decide if average or total is more important. */
/****************************************************************************************************/
SELECT TOP 10
[Average IO] = (total_logical_reads + total_logical_writes) / qs.execution_count
,[Total IO] = (total_logical_reads + total_logical_writes)
,[Execution count] = qs.execution_count
,[Individual Query] = SUBSTRING (qt.text,qs.statement_start_offset/2,
(CASE WHEN qs.statement_end_offset = -1
THEN LEN(CONVERT(NVARCHAR(MAX), qt.text)) * 2
ELSE qs.statement_end_offset END - qs.statement_start_offset)/2)
,[Parent Query] = qt.text
,DatabaseName = DB_NAME(qt.dbid)
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) as qt
--WHERE DB_NAME(qt.dbid) = 'pnl' -- Filter on a given database.
ORDER BY [Average IO] DESC; SELECT 'Identify which (cached plan) queries are the most costly by average CPU (TOP 10), across ALL databases.' AS [Step10];
/****************************************************************************************************/
/* STEP10. */
/* Purpose: Identify which queries are the most costly by CPU (TOP 10), across ALL databases. */
/* Notes: 1. This could be areas that need optimisation, maybe they crosstab with missing indexes? */
/* 2. Decide if average or total is more important. */
/****************************************************************************************************/
SELECT TOP 10
[Average CPU used] = total_worker_time / qs.execution_count
,[Total CPU used] = total_worker_time
,[Execution count] = qs.execution_count
,[Individual Query] = SUBSTRING (qt.text,qs.statement_start_offset/2,
(CASE WHEN qs.statement_end_offset = -1
THEN LEN(CONVERT(NVARCHAR(MAX), qt.text)) * 2
ELSE qs.statement_end_offset END - qs.statement_start_offset)/2)
,[Parent Query] = qt.text
,DatabaseName = DB_NAME(qt.dbid)
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) as qt
--WHERE DB_NAME(qt.dbid) = 'pnl' -- Filter on a given database.
ORDER BY [Average CPU used] DESC; SELECT 'Identify which CLR queries, use the most average CLR time (TOP 10), across ALL databases.' AS [Step11];
/****************************************************************************************************/
/* STEP011. */
/* Purpose: Identify which CLR queries, use the most avg CLR time (TOP 10), across ALL databases. */
/* Notes: 1. Decide if average or total is more important. */
/****************************************************************************************************/
SELECT TOP 10
[Average CLR Time] = total_clr_time / execution_count
,[Total CLR Time] = total_clr_time
,[Execution count] = qs.execution_count
,[Individual Query] = SUBSTRING (qt.text,qs.statement_start_offset/2,
(CASE WHEN qs.statement_end_offset = -1
THEN LEN(CONVERT(NVARCHAR(MAX), qt.text)) * 2
ELSE qs.statement_end_offset END - qs.statement_start_offset)/2)
,[Parent Query] = qt.text
,DatabaseName = DB_NAME(qt.dbid)
-- Useful fields below:
--, *
FROM sys.dm_exec_query_stats as qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) as qt
WHERE total_clr_time <> 0
--AND DB_NAME(qt.dbid) = 'pnl' -- Filter on a given database.
ORDER BY [Average CLR Time] DESC; SELECT 'Identify which (cached plan) queries are executed most often (TOP 10), across ALL databases.' AS [Step12];
/********************************************************************************************/
/* STEP12. */
/* Purpose: Identify which queries are executed most often (TOP 10), across ALL databases. */
/* Notes: 1. These should be optimised. Ensure Statistics are up to date. */
/********************************************************************************************/
SELECT TOP 10
[Execution count] = execution_count
,[Individual Query] = SUBSTRING (qt.text,qs.statement_start_offset/2,
(CASE WHEN qs.statement_end_offset = -1
THEN LEN(CONVERT(NVARCHAR(MAX), qt.text)) * 2
ELSE qs.statement_end_offset END - qs.statement_start_offset)/2)
,[Parent Query] = qt.text
,DatabaseName = DB_NAME(qt.dbid)
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) as qt
--AND DB_NAME(qt.dbid) = 'pnl' -- Filter on a given database.
ORDER BY [Execution count] DESC; SELECT 'Identify which (cached plan) queries suffer the most from blocking (TOP 10), across ALL databases.' AS [Step13];
/****************************************************************************************************/
/* STEP13. */
/* Purpose: Identify which queries suffer the most from blocking (TOP 10), across ALL databases. */
/* Notes: 1. This may have an impact on ALL queries. */
/* 2. Decide if average or total is more important. */
/****************************************************************************************************/
SELECT TOP 10
[Average Time Blocked] = (total_elapsed_time - total_worker_time) / qs.execution_count
,[Total Time Blocked] = total_elapsed_time - total_worker_time
,[Execution count] = qs.execution_count
,[Individual Query] = SUBSTRING (qt.text,qs.statement_start_offset/2,
(CASE WHEN qs.statement_end_offset = -1
THEN LEN(CONVERT(NVARCHAR(MAX), qt.text)) * 2
ELSE qs.statement_end_offset END - qs.statement_start_offset)/2)
,[Parent Query] = qt.text
,DatabaseName = DB_NAME(qt.dbid)
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) as qt
--AND DB_NAME(qt.dbid) = 'pnl' -- Filter on a given database.
ORDER BY [Average Time Blocked] DESC; SELECT 'What (cached plan) queries have the lowest plan reuse (Top 10), across ALL databases.' AS [Step14];
/************************************************************************************/
/* STEP14. */
/* What queries, in the current database, have the lowest plan reuse (Top 10). */
/* Notes: 1. */
/************************************************************************************/
SELECT TOP 10
[Plan usage] = cp.usecounts
,[Individual Query] = SUBSTRING (qt.text,qs.statement_start_offset/2,
(CASE WHEN qs.statement_end_offset = -1
THEN LEN(CONVERT(NVARCHAR(MAX), qt.text)) * 2
ELSE qs.statement_end_offset END - qs.statement_start_offset)/2)
,[Parent Query] = qt.text
,DatabaseName = DB_NAME(qt.dbid)
,cp.cacheobjtype
-- Useful fields below:
--, *
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS qt
INNER JOIN sys.dm_exec_cached_plans as cp on qs.plan_handle=cp.plan_handle
WHERE cp.plan_handle=qs.plan_handle
--AND DB_NAME(qt.dbid) = 'pnl' -- Filter on a given database.
ORDER BY [Plan usage] ASC; -- MIGHT BE USEFUL
/* /* ALTERNATIVE. */
SELECT 'Identify what indexes have a high maintenance cost.' AS [Step];
/* Purpose: Identify what indexes have a high maintenance cost. */
/* Notes : 1. This version shows writes per read, another version shows total updates without reads. */
SELECT TOP 10
DatabaseName = DB_NAME()
,TableName = OBJECT_NAME(s.[object_id])
,IndexName = i.name
,[Writes per read (User)] = user_updates / CASE WHEN (user_seeks + user_scans + user_lookups) = 0
THEN 1
ELSE (user_seeks + user_scans + user_lookups)
END
,[User writes] = user_updates
,[User reads] = user_seeks + user_scans + user_lookups
,[System writes] = system_updates
,[System reads] = system_seeks + system_scans + system_lookups
-- Useful fields below:
--, *
FROM sys.dm_db_index_usage_stats s
, sys.indexes i
WHERE s.[object_id] = i.[object_id]
AND s.index_id = i.index_id
AND s.database_id = DB_ID()
AND OBJECTPROPERTY(s.[object_id], 'IsMsShipped') = 0
ORDER BY [Writes per read (User)] DESC; -- Total Reads by most expensive IO query
SELECT TOP 10
[Total Reads] = total_logical_reads
,[Total Writes] = total_logical_writes
,[Execution count] = qs.execution_count
,[Individual Query] = SUBSTRING (qt.text,qs.statement_start_offset/2,
(CASE WHEN qs.statement_end_offset = -1
THEN LEN(CONVERT(NVARCHAR(MAX), qt.text)) * 2
ELSE qs.statement_end_offset END - qs.statement_start_offset)/2)
,[Parent Query] = qt.text
,DatabaseName = DB_NAME(qt.dbid)
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) as qt
ORDER BY [Total Reads] DESC; -- Total Writes by most expensive IO query
SELECT TOP 10
[Total Writes] = total_logical_writes
,[Total Reads] = total_logical_reads
,[Execution count] = qs.execution_count
,[Individual Query] = SUBSTRING (qt.text,qs.statement_start_offset/2,
(CASE WHEN qs.statement_end_offset = -1
THEN LEN(CONVERT(NVARCHAR(MAX), qt.text)) * 2
ELSE qs.statement_end_offset END - qs.statement_start_offset)/2)
,[Parent Query] = qt.text
,DatabaseName = DB_NAME(qt.dbid)
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) as qt
ORDER BY [Total Writes] DESC; -- Most reused queries...
SELECT TOP 10
[Run count] = usecounts
,[Query] = text
,DatabaseName = DB_NAME(qt.dbid)
,*
FROM sys.dm_exec_cached_plans cp
CROSS APPLY sys.dm_exec_sql_text(cp.plan_handle) as qt
--AND DB_NAME(qt.dbid) = 'pnl' -- Filter on a given database.
ORDER BY 1 DESC; -- The below does not give the same values as previosu step, maybe related to
-- individual qry within the parent qry?
SELECT TOP 10
[Run count] = usecounts
,[Individual Query] = SUBSTRING (qt.text,qs.statement_start_offset/2,
(CASE WHEN qs.statement_end_offset = -1
THEN LEN(CONVERT(NVARCHAR(MAX), qt.text)) * 2
ELSE qs.statement_end_offset END - qs.statement_start_offset)/2)
,[Parent Query] = qt.text
,DatabaseName = DB_NAME(qt.dbid)
,*
FROM sys.dm_exec_cached_plans cp
INNER JOIN sys.dm_exec_query_stats qs ON cp.plan_handle = qs.plan_handle
CROSS APPLY sys.dm_exec_sql_text(cp.plan_handle) as qt
--AND DB_NAME(qt.dbid) = 'pnl' -- Filter on a given database.
ORDER BY 1 DESC; */

引自连接:http://msdn.microsoft.com/en-us/magazine/cc135978.aspx?pr=blog

DMVsinSQLServer -- 备的更多相关文章

  1. Oracle冷备迁移脚本&lpar;文件系统&rpar;

    Oracle冷备迁移脚本(文件系统) 两个脚本: 配置文件生成脚本dbinfo.sh 网络拷贝到目标服务器的脚本cpdb16.sh 1. 配置文件生成脚本 #!/bin/bash #Usage: cr ...

  2. GIS部分理论知识备忘随笔

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.高斯克吕格投影带换算 某坐标的经度为112度,其投影的6度带和3度带 ...

  3. mysql&plus;mycat搭建稳定高可用集群,负载均衡,主备复制,读写分离

    数据库性能优化普遍采用集群方式,oracle集群软硬件投入昂贵,今天花了一天时间搭建基于mysql的集群环境. 主要思路 简单说,实现mysql主备复制-->利用mycat实现负载均衡. 比较了 ...

  4. CentOS系统MySQL双机热备配置

    1  概述 在集成项目中需要应对不同环境下的安装配置,主流操作系统大致可以分为三种:Linux.Windows以及UNIX.其中Linux备受青睐的主要原因有两个: 首先,Linux作为*软件有两个 ...

  5. python序列,字典备忘

    初识python备忘: 序列:列表,字符串,元组len(d),d[id],del d[id],data in d函数:cmp(x,y),len(seq),list(seq)根据字符串创建列表,max( ...

  6. 一张&OpenCurlyDoubleQuote;神图”看懂单机&sol;集群&sol;热备&sol;磁盘阵列(RAID)

    单机部署(stand-alone):只有一个饮水机提供服务,服务只部署一份 集群部署(cluster):有多个饮水机同时提供服务,服务冗余部署,每个冗余的服务都对外提供服务,一个服务挂掉时依然可用 热 ...

  7. mysql主备(centos6&period;4)

    服务器基本环境: 两台centos6.4.iptables  diabled .selinux  disabled 两台的hosts解析 #yum install mysql -y  //这个一定要装 ...

  8. Keepalived&plus;LVS&plus;nginx双机热备

    Keepalived简介 什么是Keepalived呢,keepalived观其名可知,保持存活,在网络里面就是保持在线了, 也就是所谓的高可用或热备,用来防止单点故障的发生. Keepalived采 ...

  9. Oracle备库TNS连接失败的分析

    今天在测试12c的temp_undo的时候,准备在备库上测试一下,突然发现备库使用TNS连接竟然失败. 抛出的错误如下: $ sqlplus sys/oracle@testdb as sysdba S ...

随机推荐

  1. 简单的ADO&period;NET连接数据小样例

    ADO.NET连接数据库的样例如下: using System; using System.Collections.Generic; using System.ComponentModel; usin ...

  2. 转:怎样在VMware ESXi上 克隆虚拟机

    Cloning virtual machines on VMware ESXi 翻译自http://www.dedoimedo.com/computers/vmware-esxi-clone-mach ...

  3. laravel homestead

    laravel homestead真是个好东西啊,折腾了很长时间,终于ok啦. 安装成功之后,在-目录下有个homstead,进入执行vagrant up clzdeMBP:Homestead clz ...

  4. 【Android】数据库的简单应用——升级数据库

    假如我们已经创建好了一个数据库,随着功能需求的增加,想在数据库中再添加一个表,如果直接在之前的代码中插入一个表,会发现创建表失败,这是因为该数据库已经存在.该如何解决呢? 1.卸载程序,重新编译安装. ...

  5. hibernate&lowbar;validator&lowbar;03

    约束继承 如果要验证的对象继承于某个父类或者实现了某个接口,那么定义在父类或者接口中的约束会在验证这个对象的时候被自动加载,如同这些约束定义在这个对象所在的类中一样. 让我们来看看下面的示例: pac ...

  6. CSS截取字符串

    /*溢出的字...处理*/ .updatecsssubstring { text-overflow: ellipsis; -o-text-overflow: ellipsis; white-space ...

  7. ABAP中的枚举对象

    枚举对象是枚举类型的数据对象.枚举对象只能包含类型为枚举类型的枚举值.ABAP从版本7.51开始支持它们. 这是一种常见的模式.在ABAP 7.51之前,人们通常用如下方式实现类似的功能: CLASS ...

  8. 美化博客CSS

    title: 美化博客CSS date: 2019/01/19 14:28:59 --- 美化博客CSS 可以去这里看下好看的样式 修改下文档的css,博客园是在页面定制CSS代码,我这里修改了下标题 ...

  9. G - Galactic Collegiate Programming Contest Kattis - gcpc (set使用)

    题目链接: G - Galactic Collegiate Programming Contest Kattis - gcpc 题目大意:当前有n个人,一共有m次提交记录,每一次的提交包括两个数,st ...

  10. HDU 2208 唉,可爱的小朋友(DFS)

    唉,可爱的小朋友 Time Limit: 10000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total S ...