監(jiān)控數(shù)據(jù)庫運(yùn)行
下面是整理、收集監(jiān)控數(shù)據(jù)庫運(yùn)行的一些常用腳本,也是MS SQL 日常維護(hù)管理常用腳本(一)的續(xù)集,歡迎大家補(bǔ)充、提意見。
查看數(shù)據(jù)庫登錄名信息
Code Snippet
- SELECT name AS LoginName ,
- dbname AS DefaultDB ,
- createdate AS CreateDate,
- updatedate AS UpdateDate,
- language AS Language ,
- CASE WHEN isntname = 1 THEN 'NT USER'
- ELSE 'SQL USER' END AS UserType
- FROM syslogins;
查看數(shù)據(jù)庫用戶信息 SELECT * FROM sysusers; 查看用戶擁有的服務(wù)器角色
方法1: 用SSMS管理工具查看
方法2: 腳本查詢
查看用戶角色
- SELECT name ,
- CASE WHEN sysadmin = 1 THEN 'yes' ELSE '' END AS IsSysadmin ,
- CASE WHEN dbcreator = 1 THEN 'yes' ELSE '' END AS IsDbCreate ,
- CASE WHEN securityadmin= 1 THEN 'yes' ELSE '' END AS IsSecurityadmin ,
- CASE WHEN bulkadmin = 1 THEN 'yes' ELSE '' END AS IsBulkadmin ,
- CASE WHEN diskadmin = 1 THEN 'yes' ELSE '' END AS IsDiskadmin ,
- CASE WHEN processadmin = 1 THEN 'yes' ELSE '' END AS IsProcessadmin ,
- CASE WHEN serveradmin = 1 THEN 'yes' ELSE '' END AS IsServeradmin ,
- CASE WHEN setupadmin = 1 THEN 'yes' ELSE '' END AS IsSetupadmin
- FROM syslogins
- --WHERE NAME='loginname'
查看最大工作線程數(shù)
Code Snippet
- SELECT max_workers_count
- FROM sys.dm_os_sys_info
查看當(dāng)前用戶進(jìn)程的會話ID
SELECT @@SPID
查詢當(dāng)前會話使用哪種協(xié)議
Code Snippet
- SELECT net_transport
- FROM sys.dm_exec_connections
- WHERE session_id = @@SPID;
查看當(dāng)前連接的會話信息
--進(jìn)程號1--50是SQL Server系統(tǒng)內(nèi)部用的 SELECT * FROM sys.dm_exec_sessions WHERE session_id >=51 --查看某臺機(jī)器的連接會話信息 SELECT * FROM sys.dm_exec_sessions WHERE session_id >=51 AND host_name='PO130018801' --查看某個登錄名的連接會話信息 SELECT * FROM sys.dm_exec_sessions WHERE session_id >=51 AND login_name='username' --查看活動的連接會話信息 SELECT * FROM sys.dm_exec_sessions WITH(NOWAIT) WHERE session_id >=51 AND status ='running' --查找連接到服務(wù)器的用戶并返回每個用戶的會話數(shù) SELECT login_name , COUNT(session_id) AS session_count FROM sys.dm_exec_sessions GROUP BY login_name ;
查看正在執(zhí)行的SQL語句
方法1: 選擇數(shù)據(jù)庫實(shí)例,單擊右鍵,選擇”活動監(jiān)視器“,監(jiān)控/查看正在執(zhí)行的SQL
方法2: profile去跟蹤,比較耗費(fèi)資源。
方法3:
Code Snippet
- SELECT[Spid] = session_Id ,
- ecid ,
- [Database] = DB_NAME(sp.dbid) ,
- [User] = nt_username ,
- [Status] = er.status ,
- [Wait] = wait_type ,
- [Individual Query] = SUBSTRING(qt.text, er.statement_start_offset / 2,
- ( CASE WHEN er.statement_end_offset = -1
- THEN LEN(CONVERT(NVARCHAR(MAX), qt.text))
- * 2
- ELSE er.statement_end_offset
- END - er.statement_start_offset ) / 2) ,
- [Parent Query] = qt.text ,
- Program = program_name ,
- Hostname ,
- nt_domain ,
- start_time
- FROMsys.dm_exec_requests er
- INNER JOIN sys.sysprocesses sp ON er.session_id = sp.spid
- CROSS APPLY sys.dm_exec_sql_text(er.sql_handle) AS qt
- WHEREsession_Id >= 51
方法4:
Code Snippet
- SELECT m.session_id ,
- m.start_time ,
- m.command ,
- m.wait_type ,
- m.cpu_time ,
- CAST(s.text AS VARCHAR(1000)) AS sqlText
- FROMmaster.sys.dm_exec_requests m WITH ( NOLOCK )
- CROSS APPLY fn_get_sql(m.sql_handle) s
-
- SELECT r.session_id,
- r.start_time ,
- r.command ,
- r.wait_type ,
- r.cpu_time ,
- s.text
- FROMsys.dm_exec_requests r
- CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) s
--查看某個會話ID正在執(zhí)行的SQL
Code Snippet
- SELECT m.session_id ,
- m.start_time ,
- m.command ,
- m.wait_type ,
- m.cpu_time ,
- CAST(s.text AS VARCHAR(1000)) AS sqlText
- FROMmaster.sys.dm_exec_requests m WITH ( NOLOCK )
- CROSS APPLY fn_get_sql(m.sql_handle) s
- WHEREm.session_id = 342
-
- SELECT r.session_id ,
- r.start_time ,
- r.command ,
- r.wait_type ,
- r.cpu_time ,
- s.text
- FROM sys.dm_exec_requests r
- CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) s
- WHERE r.seesion_id =342
查看SQL SERVER進(jìn)程執(zhí)行的語句
Code Snippet
- USE master
-
- DECLARE @spid INT ;
-
- DECLARE @sql_handle BINARY(20) ;
-
- SET @spid = 56
-
- SELECT@sql_handle = sql_handle
- FROMsysprocesses AS A WITH ( NOLOCK )
- WHEREspid = @spid ;
-
- SELECTtext
- FROM::fn_get_sql(@sql_handle) ;
查找TOP N語句
按平均 CPU 時間返回排名前十個的查詢的相關(guān)信息。此示例將根據(jù)查詢的查詢哈希對查詢進(jìn)行聚合,以便按照查詢的累積資源消耗來分組在邏輯上等效的查詢。 --注意:SQL 2005 某些版本,沒有sys.dm_exec_query_stats系統(tǒng)動態(tài)視圖沒有query_hash視圖。
Code Snippet
- USE DBNAME;
- GO
- SELECT TOP 10 query_stats.query_hash AS "Query Hash",
- SUM(query_stats.total_worker_time) /
- SUM(query_stats.execution_count) AS "Avg CPU Time",
- MIN(query_stats.statement_text) AS "Statement Text"
- FROM
- (SELECT QS.*,
- SUBSTRING(ST.text,(QS.statement_start_offset/2) + 1,
- ((CASE statement_end_offset
- WHEN -1 THEN DATALENGTH(st.text)
- ELSE QS.statement_end_offset END
- - QS.statement_start_offset)/2) + 1) AS statement_text
- FROM sys.dm_exec_query_stats AS QS
- CROSS APPLY sys.dm_exec_sql_text(QS.sql_handle) as ST) as query_stats
- GROUP BY query_stats.query_hash
- ORDER BY 2 DESC;
- GO
查看會話阻塞/死鎖信息
方法1:查看那個引起阻塞,查看blk不為0的記錄,如果存在阻塞進(jìn)程,則是該阻塞進(jìn)程的會話 ID。否則該列為零。
EXEC sp_who active
方法2:查看那個引起阻塞,查看字段BlkBy,這個能夠得到比sp_who更多的信息。
EXEC sp_who2 active
方法3:sp_lock 系統(tǒng)存儲過程,報告有關(guān)鎖的信息,但是不方便定位問題
方法4:sp_who_lock存儲過程
Code Snippet
- USE master;
- GO
-
- SET ANSI_NULLS ON;
- GO
-
- SET QUOTED_IDENTIFIER ON;
- GO
-
- IF EXISTS(SELECT 1 FROM sysobjects WHERE id=OBJECT_ID(N'sp_who_lock')
- AND OBJECTPROPERTY(id, 'IsProcedure') =1)
- DROP PROCEDURE sp_who_lock;
- GO
-
- --==================================================================================================
- -- ProcedureName : sp_who_lock
- -- Author : 作者不詳,出自網(wǎng)絡(luò)
- -- CreateDate : 2013-05-13
- -- Description : 查看阻塞和死鎖信息
- /**************************************************************************************************
- Parameters : 參數(shù)說明
- ***************************************************************************************************
- 無參存儲過程
- ***************************************************************************************************
- Modified Date Modified User Version Modified Reason
- ***************************************************************************************************
- 2013-06-03 Kerry V01.00.01 調(diào)整存儲過程格式,代碼部分修改以及增加注釋信息
- ***************************************************************************************************/
- --=================================================================================================
-
- CREATE PROCEDURE sp_who_lock
- AS
- BEGIN
-
- DECLARE @spid INT;
- DECLARE @block INT;
- DECLARE @RowCount INT;
- DECLARE @RowIndex INT;
-
- --創(chuàng)建臨時表,保持被阻塞或正阻塞其他SQL的SQL語句信息
- CREATE TABLE #tmp_lock_who
- (
- id INT IDENTITY(1, 1) ,
- spid SMALLINT ,
- block SMALLINT
- )
-
-
- IF @@ERROR<>0 RETURN @@ERROR;
-
- INSERT INTO #tmp_lock_who
- (
- spid ,
- block
- )
- SELECT 0 ,
- blocked
- FROM ( SELECT *
- FROM sysprocesses
- WHERE blocked > 0
- ) a
- WHERE NOT EXISTS( SELECT *
- FROM ( SELECT *
- FROM sysprocesses
- WHERE blocked > 0
- ) b
- WHERE a.blocked = spid )
- UNION
- SELECT spid ,
- blocked
- FROM sysprocesses
- WHERE blocked > 0;
-
-
- IF @@ERROR<>0 RETURN @@ERROR;
-
-
- -- 找到臨時表的記錄數(shù)
- SELECT@RowCount = COUNT(1) ,
- @RowIndex = 1
- FROM#tmp_lock_who
-
-
- IF @@ERROR<>0 RETURN @@ERROR;
-
- IF@RowCount=0
- SELECT N'現(xiàn)在沒有阻塞和死鎖信息' AS MESSAGE;
-
-
- -- -- 循環(huán)開始
- WHILE @RowIndex <= @RowCount
- BEGIN
- -- 取第一條記錄
- SELECT @spid = spid,
- @block = block
- FROM #tmp_lock_who
- WHERE Id = @RowIndex
-
- IF @spid = 0
- SELECT N'引起數(shù)據(jù)庫死鎖的是: ' + CAST(@block AS VARCHAR(10))
- + N'進(jìn)程號,其執(zhí)行的SQL語法如下';
- ELSE
- SELECT N'進(jìn)程號SPID:' + CAST(@spid AS VARCHAR(10)) + N'被進(jìn)程號SPID:'
- + CAST(@block AS VARCHAR(10)) +'阻塞,其當(dāng)前進(jìn)程執(zhí)行的SQL語法如下';
-
- DBCC INPUTBUFFER(@block )
-
-
- SET @RowIndex = @RowIndex + 1;
-
- END;
-
- DROP TABLE #tmp_lock_who;
-
- RETURN 0;
- END
方法5:右鍵服務(wù)器-選擇“活動和監(jiān)視器”,查看進(jìn)程選項(xiàng)。注意“任務(wù)狀態(tài)”字段。
方法6:右鍵服務(wù)名稱-選擇報表-標(biāo)準(zhǔn)報表-活動-所有正在阻塞的事務(wù)。
小結(jié):總結(jié)之后,才發(fā)現(xiàn)居然有這么多方法,MGD,系統(tǒng)的整理、梳理知識點(diǎn)是非常有必要的,你能更全面、深入的了解。
查看內(nèi)存狀態(tài)
dbcc memorystatus
具體如何分析,請查看官方文檔http://support.microsoft.com/kb/907877/zh-cn
查看腳本執(zhí)行時間
方法1: 查看SSMS管理器,查詢窗口右下角 方法2:
Code Snippet
- DECLARE @exectime DATETIME
- SELECT@exectime = GETDATE()
- --SQL 語句
- PRINT N'SQL執(zhí)行耗時:' + CONVERT(VARCHAR(10), DATEDIFF(ms, @exectime, GETDATE()))
方法3:
SET STATISTICS TIME ON
--SQL 語句
查看進(jìn)程正在執(zhí)行的SQL語句
dbcc inputbuffer ()
查看那些表缺少索引
下面語句功能強(qiáng)大,執(zhí)行結(jié)果受統(tǒng)計信息的影響
Code Snippet
- SELECT sys.objects.name table_name,
- mid.statement full_name,
- (migs.avg_total_user_cost * migs.avg_user_impact) *(migs.user_seeks + migs.user_scans) AS Impact,
- migs.avg_user_impact *(migs.user_seeks + migs.user_scans) Avg_Estimated_Impact,
- 'CREATE NONCLUSTERED INDEX IDX_' + sys.objects.name + '_N ON '
- + sys.objects.name COLLATE DATABASE_DEFAULT
- + ' ( ' + IsNull(mid.equality_columns, '')
- + CASE WHEN mid.inequality_columns IS NULL
- THEN ''
- ELSE
- CASE WHEN mid.equality_columns IS NULL
- THEN ''
- ELSE ','
- END + mid.inequality_columns
- END + ' ) '
- + CASE WHEN mid.included_columns IS NULL
- THEN ''
- ELSE 'INCLUDE (' + mid.included_columns + ')' END
- + ';' AS CreateIndexStatement,
- mid.equality_columns,
- mid.inequality_columns,
- mid.included_columns
- FROM sys.dm_db_missing_index_group_stats AS migs
- INNER JOIN sys.dm_db_missing_index_groups AS mig ON migs.group_handle = mig.index_group_handle
- INNER JOIN sys.dm_db_missing_index_details AS mid ON mig.index_handle = mid.index_handle
- AND mid.database_id = DB_ID()
- INNER JOIN sys.objects WITH (nolock) ON mid.OBJECT_ID = sys.objects.OBJECT_ID
- WHERE (migs.group_handle IN
- (
- SELECT TOP (500) group_handle
- FROM sys.dm_db_missing_index_group_stats WITH (nolock)
- ORDER BY (avg_total_user_cost * avg_user_impact) *(user_seeks + user_scans) DESC))
- AND OBJECTPROPERTY(sys.objects.OBJECT_ID, 'isusertable')=1
- --ORDER BY [Impact] DESC, [full_name] DESC
- ORDER BY [table_name], [Impact] desc
查看應(yīng)該被移除的索引
查看那些多余的、應(yīng)該被移除的索引
SQL 1:
Code Snippet
- SELECT OBJECTNAME = OBJECT_NAME(I.OBJECT_ID),
- INDEXNAME = I.NAME,
- I.INDEX_ID
- FROM SYS.INDEXES I
- JOIN SYS.OBJECTS O ON I.OBJECT_ID = O.OBJECT_ID
- WHERE OBJECTPROPERTY(O.OBJECT_ID,'IsUserTable') = 1
- AND I.INDEX_ID NOT IN(
- SELECT S.INDEX_ID
- FROM SYS.DM_DB_INDEX_USAGE_STATS S
- WHERE S.OBJECT_ID = I.OBJECT_ID
- AND I.INDEX_ID = S.INDEX_ID
- AND DATABASE_ID = DB_ID())
- ORDER BY OBJECTNAME, I.INDEX_ID, INDEXNAME ASC
SQL 2: 分析下面語句,移除那些沒有必要的索引
Code Snippet
- SELECT DB_NAME(database_id) AS N'DataBaseName' ,
- OBJECT_NAME(U.object_id) AS N'Table_Name' ,
- I.name AS N'Index_Name' ,
- user_seeks AS N'用戶索引查找次數(shù)',
- user_scans AS N'用戶索引掃描次數(shù)',
- last_user_seek AS N'最后查找時間' ,
- last_user_scan AS N'最后掃描時間' ,
- rows AS N'表中的行數(shù)'
- FROM sys.dm_db_index_usage_stats AS U
- INNER JOIN sys.indexes I ON U.index_id= I.index_idAND U.object_id= I.object_id
- INNER JOIN sysindexesT ON I.object_id = T.id
- WHERE database_id= DB_ID('DbName')
- AND OBJECT_NAME(U.object_id)='TableName'
- ORDER BY user_seeks, user_scans, object_name(U.object_id);
|