DMVsinSQLServer -- 备
/******************************************************************************************************* 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 -- 备的更多相关文章
- Oracle冷备迁移脚本(文件系统)
Oracle冷备迁移脚本(文件系统) 两个脚本: 配置文件生成脚本dbinfo.sh 网络拷贝到目标服务器的脚本cpdb16.sh 1. 配置文件生成脚本 #!/bin/bash #Usage: cr ...
- GIS部分理论知识备忘随笔
文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.高斯克吕格投影带换算 某坐标的经度为112度,其投影的6度带和3度带 ...
- mysql+mycat搭建稳定高可用集群,负载均衡,主备复制,读写分离
数据库性能优化普遍采用集群方式,oracle集群软硬件投入昂贵,今天花了一天时间搭建基于mysql的集群环境. 主要思路 简单说,实现mysql主备复制-->利用mycat实现负载均衡. 比较了 ...
- CentOS系统MySQL双机热备配置
1 概述 在集成项目中需要应对不同环境下的安装配置,主流操作系统大致可以分为三种:Linux.Windows以及UNIX.其中Linux备受青睐的主要原因有两个: 首先,Linux作为自由软件有两个 ...
- python序列,字典备忘
初识python备忘: 序列:列表,字符串,元组len(d),d[id],del d[id],data in d函数:cmp(x,y),len(seq),list(seq)根据字符串创建列表,max( ...
- 一张“神图”看懂单机/集群/热备/磁盘阵列(RAID)
单机部署(stand-alone):只有一个饮水机提供服务,服务只部署一份 集群部署(cluster):有多个饮水机同时提供服务,服务冗余部署,每个冗余的服务都对外提供服务,一个服务挂掉时依然可用 热 ...
- mysql主备(centos6.4)
服务器基本环境: 两台centos6.4.iptables diabled .selinux disabled 两台的hosts解析 #yum install mysql -y //这个一定要装 ...
- Keepalived+LVS+nginx双机热备
Keepalived简介 什么是Keepalived呢,keepalived观其名可知,保持存活,在网络里面就是保持在线了, 也就是所谓的高可用或热备,用来防止单点故障的发生. Keepalived采 ...
- Oracle备库TNS连接失败的分析
今天在测试12c的temp_undo的时候,准备在备库上测试一下,突然发现备库使用TNS连接竟然失败. 抛出的错误如下: $ sqlplus sys/oracle@testdb as sysdba S ...
随机推荐
- hdu 4710 Balls Rearrangement
题意就不说了,刚开始做我竟然傻傻地去模拟,智商捉急啊~~超时是肯定的 求出 a ,b 的最小公倍数,因为n够长的话,就会出现循环,所以就不要再做不必要的计算了.如果最小公倍数大于n的话,就直接计算n吧 ...
- Java split方法源码分析
Java split方法源码分析 public String[] split(CharSequence input [, int limit]) { int index = 0; // 指针 bool ...
- Python 提示 no module named win32api
Windows下运行Python程序 提示错误 说是没有win32api的模块 解决办法 : 安装pywin32对应于Python的版本 可从https://sourceforge.net/pro ...
- MySQL----information-schema数据库相关权限的说明。
MySQL中的information_schema数据库比较特别有如下几个要注意的地方. 1.就算是一个新创建的用户,也就是说这个用户只有一个usage权限.它都可以查看informatoin_sch ...
- gridview外边距
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区. 您需要 登录 才可以下载或查看,没有帐号?注册 x 本帖最后由 同舟 于 2013-9-30 11:44 编辑 最新项目需要个单行显示功能键 ...
- 传智播客C/C++学员荣膺微软&Cocos 2d-x黑客松最佳创新奖
6月30日,历时32小时的微软开放技术Cocos 2d-x 编程黑客松在北京望京微软大厦成功落下帷幕,这是微软开放技术首次联合Cocos 2d-x 在中国举办黑客松.此次活动共有包括传智播客C/ ...
- poj3589---判断两个数有多接近
#include <stdio.h> #include <stdlib.h> int main() { ],s2[]; int a,b,i,j,n; scanf("% ...
- ubuntu14.04 qt4 C++开发环境搭建
preFace:文章包括gnome,vnc-server,qt4安装配置及集成; apt-get update && apt-get upgrade; <一,组件软件包安装> ...
- IE 创建条件样式
1.HTML 注释 <div id="header">Header Section</div> <!-- End Header Section Con ...
- Python学习笔记6-异常捕获取
#--encoding:utf-8-- try: float('abc') except Exception,e: print e try: float(1.2) except Exception,e ...