1. 查看sql server代理中作業的運行狀況的腳本
-- descr : a simple sql script to view sql server jobs run status -- last_run_status 1:success 0:fail select category = jc.name, category_id = jc.category_id, job_name = j.name, job_enabled = j.enabled, last_run_time = cast(js.last_run_date as varchar(10)) + '-' + cast(js.last_run_time as varchar(10)), last_run_duration = js.last_run_duration, last_run_status = js.last_run_outcome, last_run_msg = js.last_outcome_message + cast(nullif(js.last_run_outcome,1) as varchar(2)), job_created = j.date_created, job_modified = j.date_modified from msdb.dbo.sysjobs j inner join msdb.dbo.sysjobservers js on j.job_id = js.job_id inner join msdb.dbo.syscategories jc on j.category_id = jc.category_id where j.enabled = 1 and js.last_run_outcome in (0,1,3,5) -- 0:Fail 1:Succ 3:Cancel 5:First run and jc.category_id not between 10 and 20 -- repl --and js.last_run_outcome = 0 只用於查看失敗的作業
2. 查看always on 同步狀態(隊列情況)
SELECT ar.replica_server_name AS [副本名稱] , ar.availability_mode_desc as [同步模式], DB_NAME(dbr.database_id) AS [數據庫名稱] , dbr.database_state_desc AS [數據庫狀態], dbr.synchronization_state_desc AS [同步狀態], dbr.synchronization_health_desc AS [同步健康狀態], ISNULL(CASE dbr.redo_rate WHEN 0 THEN -1 ELSE CAST(dbr.redo_queue_size AS FLOAT) / dbr.redo_rate END, -1) AS [Redo延遲(秒)] , ISNULL(CASE dbr.log_send_rate WHEN 0 THEN -1 ELSE CAST(dbr.log_send_queue_size AS FLOAT) / dbr.log_send_rate END, -1) AS [Log傳送延遲(秒)] , dbr.redo_queue_size AS [Redo等待隊列(KB)] , dbr.redo_rate AS [Redo速率(KB/S)] , dbr.log_send_queue_size AS [Log傳送等待隊列(KB)] , dbr.log_send_rate AS [Log傳送速率(KB\S)] FROM [master].sys.availability_replicas AS AR INNER JOIN [master].sys.dm_hadr_database_replica_states AS dbr ON ar.replica_id = dbr.replica_id WHERE dbr.redo_queue_size IS NOT NULL order by DB_NAME(dbr.database_id)
3. 查詢當前數據庫的腳本(語句)的運行情況(dbcc freeproccache 之後執行次數會再次刷新)
SELECT creation_time N'語句編譯時間' ,last_execution_time N'上次執行時間' ,execution_count N'執行次數' ,case datediff(ss,creation_time,last_execution_time) when 0 then 0 else execution_count/datediff(ss,creation_time,last_execution_time) end N'每秒執行次數' ,total_physical_reads N'物理讀取總次數' ,total_logical_reads/execution_count N'每次邏輯讀次數' ,total_logical_reads N'邏輯讀取總次數' ,total_logical_writes N'邏輯寫入總次數' , total_worker_time/1000 N'所用的CPU總時間ms' , total_elapsed_time/1000 N'總花費時間ms' , (total_elapsed_time / execution_count)/1000 N'平均時間ms' ,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) N'執行語句' ,db_name(st.dbid) as dbname,st.objectid FROM sys.dm_exec_query_stats AS qs CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) st where last_execution_time >= dateadd(MINUTE,-1,getdate()) and 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) not like '%fetch%' ORDER BY execution_count DESC;
4. 查詢當前數據庫正在執行的語句
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,hostprocess ,loginame ,kpid ,nt_domain , start_time FROM sys.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 WHERE session_Id > 50 /* Ignore system spids.*/
5. 查詢阻塞情況
SELECT wt.blocking_session_id AS BlockingSessesionId ,sp.program_name AS ProgramName ,COALESCE(sp.LOGINAME, sp.nt_username) AS HostName ,ec1.client_net_address AS ClientIpAddress ,db.name AS DatabaseName ,wt.wait_type AS WaitType ,ec1.connect_time AS BlockingStartTime ,wt.WAIT_DURATION_MS/1000 AS WaitDuration ,ec1.session_id AS BlockedSessionId ,h1.TEXT AS BlockedSQLText ,h2.TEXT AS BlockingSQLText FROM sys.dm_tran_locks AS tl INNER JOIN sys.databases db ON db.database_id = tl.resource_database_id INNER JOIN sys.dm_os_waiting_tasks AS wt ON tl.lock_owner_address = wt.resource_address INNER JOIN sys.dm_exec_connections ec1 ON ec1.session_id = tl.request_session_id INNER JOIN sys.dm_exec_connections ec2 ON ec2.session_id = wt.blocking_session_id LEFT OUTER JOIN master.dbo.sysprocesses sp ON SP.spid = wt.blocking_session_id CROSS APPLY sys.dm_exec_sql_text(ec1.most_recent_sql_handle) AS h1 CROSS APPLY sys.dm_exec_sql_text(ec2.most_recent_sql_handle) AS h2
--==================================== --查看正在執行的SQL的阻塞情況 SELECT R.session_id, R.command, R.blocking_session_id, R.wait_type, R.wait_resource FROM sys.dm_exec_requests AS R WHERE R.session_id>55 AND R.session_id<>@@SPID
--================================================================= --查看阻塞鏈 WITH T1 AS ( SELECT S.session_id , ISNULL(RS.blocking_session_id , 0) AS blocking_session_id , CAST('' AS NVARCHAR(200)) AS BlockStep , AS BlockNum FROM [sys].[dm_exec_sessions] AS S WITH ( NOLOCK ) LEFT JOIN [sys].[dm_exec_requests] RS WITH ( NOLOCK ) ON S.session_id = RS.session_id WHERE S.session_id IN ( SELECT RS1.blocking_session_id FROM [sys].[dm_exec_requests] RS1 ) AND ISNULL(RS.blocking_session_id , 0) = 0 UNION ALL SELECT RS.session_id , RS.blocking_session_id , CAST(( '-->' + CAST(RS.blocking_session_id AS NVARCHAR(200)) + T1.BlockStep ) AS NVARCHAR(200)) AS BlockStep , + T1.BlockNum AS BlockNum FROM [sys].[dm_exec_requests] RS INNER JOIN T1 ON RS.blocking_session_id = T1.session_id ) SELECT session_id , blocking_session_id , ( CASE WHEN T1.BlockStep = '' THEN 'KILL ' + CAST(T1.session_id AS NVARCHAR(200)) ELSE T1.BlockStep END ) AS BlockStep , BlockNum FROM T1
6. 查詢數據庫日誌文件的大小
dbcc sqlperf(logspace)
列名 | 定義 |
---|---|
Database Name |
數據庫名稱,爲該數據庫顯示日誌統計信息。 |
Log Size (MB) |
分配給日誌的當前大小。該大小始終小於最初爲日誌空間分配的大小,因爲 SQL Server 2005 數據庫引擎保留了一小部分磁盤空間用於存放內部標頭信息。 |
Log Space Used (%) |
事務日誌信息當前所佔用的日誌文件的百分比。 |
Status |
日誌文件的狀態。始終爲 0。 |
7. 遷移登錄用戶
select 'create login [' + p.name + '] ' + case when p.type in('U','G') then 'from windows ' else '' end + 'with ' + case when p.type = 'S' then 'password = ' + master.sys.fn_varbintohexstr(l.password_hash) + ' hashed, ' + 'sid = ' + master.sys.fn_varbintohexstr(l.sid) + ', check_expiration = ' + case when l.is_expiration_checked > 0 then 'ON, ' else 'OFF, ' end + 'check_policy = ' + case when l.is_policy_checked > 0 then 'ON, ' else 'OFF, ' end + case when l.credential_id > 0 then 'credential = ' + c.name + ', ' else '' end else '' end + 'default_database = ' + p.default_database_name + case when len(p.default_language_name) > 0 then ', default_language = "' + p.default_language_name +'"' else '''' end from sys.server_principals p left join sys.sql_logins l on p.principal_id = l.principal_id left join sys.credentials c on l.credential_id = c.credential_id where p.type in('S','U','G') and p.name <> 'sa'
8. 檢查文件空間的方法:
使用 exec sp_spaceused 查看的時候,結果比較籠統,不過也是可行的;
建議同時運行下面兩條命令:
use<數據庫> go dbcc showfilestats go dbcc sqlperf(logspace) go
其中“dbcc showfilestats”命令會以Extent爲單位,統計當前數據庫下所有數據文件裏有多少個Extent,其中有多少個被使用過了,一個Extent是64K,乘一下即可得到數據文件大小,該命令直接從系統分配頁面上面讀取區分配信息,能夠快速準確地計算出一個數據庫數據文件區的總數和已使用過的區的數目,而系統分配頁上的信息永遠是實時更 新的,所以這種統計方法比較準確可靠。在服務器負載很高的情況下也能安全執行,不會增加額外系統負擔;
“dbcc sqlperf(logspace)”命令的輸出非常淺顯易懂。它返回SQL裏所有數據庫的日誌文件當前使用量,該命令的輸出也非常快速準確,使用安全。
運行以下查詢,可以得到具體庫中表的具體空間使用信息:
use xxxxDB --需要查詢的庫名 SELECT o.name as name , SUM (p.reserved_page_count) as reserved_page_count, SUM (p.used_page_count) as used_page_count , SUM ( CASE WHEN (p.index_id <2) THEN (p.in_row_data_page_count + p.lob_used_page_count + p.row_overflow_used_page_count) ELSE p.lob_used_page_count + p.row_overflow_used_page_count END ) as DataPages, SUM ( CASE WHEN (p.index_id <2) THEN row_count ELSE 0 END ) as rowCounts FROM sys.dm_db_partition_stats as p join sys.objects as o on p.object_id = o.object_id group by o.name order by reserved_page_count desc
輸出結果
第一列name是每個表的名字。
SQL Server在使用數據頁的時候,爲了提高速度,會先把一些頁面一次預留”reserve”給表格,然後真正有數據插入的時候,再使用。所以這裏有兩 列,Reserved_page_count和Used_page_count。兩列的結果相差一般不會很多。所以粗略來 講,Reserved_page_count*8K,就是這張表格佔用的空間大小。
DataPages是這張表數據本身佔有的空間。因此,(Used_page_count – DataPages)就是索引所佔有的空間。索引的個數越多,需要的空間也會越多。
RowCounts,是現在這個表裏有多少行數據。
9. 查看sqlserver中表、存儲過程、視圖等創建以及修改時間:
a)、直接通過對象資源管理詳細信息查看(選中相關項,按F7即可)。
b)、直接通過sql語句查看
--查看錶的結構
select column_name,data_type from information_schema.columns where table_name = '表名'
--查看用戶表的創建時間以及修改時間 select name,create_date ,modify_date from sys.all_objects where type_desc in ('USER_TABLE') --查看存儲過程的創建時間以及修改時間 select name,create_date ,modify_date from sys.all_objects where type_desc in ('SQL_STORED_PROCEDURE') --查看視圖的創建時間以及修改時間 select name,create_date ,modify_date from sys.all_objects where type_desc in ('VIEW')
10. 查看數據庫具體表上的索引的使用情況
use xxx --改成要查看的數據庫 select db_name(database_id) as N'數據庫名稱', object_name(a.object_id) as N'表名', b.name N'索引名稱', user_seeks N'用戶索引查找次數', user_scans N'用戶索引掃描次數', last_user_seek N'最後查找時間', last_user_scan N'最後掃描時間', rows as N'表中的行數' from sys.dm_db_index_usage_stats a join sys.indexes b on a.index_id = b.index_id and a.object_id = b.object_id join sysindexes c on c.id = b.object_id where database_id=db_id('xxx') ---改成要查看的數據庫 and object_name(a.object_id) not like 'sys%' and object_name(a.object_id) = 'xxx' --改成要查看的表名,此步可省略(即查看某庫所有索引) order by user_scans desc
11. 查看某個表的具體的增長情況
--每十分鐘統計某表的數據變動情況(副本庫查詢) --通過該char(15)可改變統計時間間隔,時間列如 2016-05-17 15:09:53.627 use xxxxDB select convert(char(15),時間列,120),count(1) from 表名 with (nolock) where 自增列 > (select max(自增列)-條目數 from 表名 ) group by convert(char(15),時間列,120)
12. 查詢指定數據的每月的備份文件增長情況
select AVG(backup_size)/1024/1024 as "backup_size MB" ,convert(char(7),backup_finish_date,120) as backup_date FROM msdb.dbo.backupset WHERE [database_name] = N'xxxxxDB' and server_name = 'yyyyy' group by convert(char(7),backup_finish_date,120) order by convert(char(7),backup_finish_date,120) -- 按月統計指定數據庫的增長 -- xxxxxDB 數據庫 -- yyyyy 數據庫所在服務器的主機名
13. 查詢得到1-100的連續數字(區間可改)
select number from master..spt_values where type = 'p' and number between 1 and 100
14. 查詢具體表的行數
SELECT rows FROM sysindexes WHERE id =OBJECT_ID('table_name') AND indid <2
15. 查看數據庫服務器上所有的IO負載的排名(IO負載分佈狀況)
-- Get I/O utilization by database (Query 31) (IO Usage By Database) WITH Aggregate_IO_Statistics AS (SELECT DB_NAME(database_id) AS [Database Name], CAST(SUM(num_of_bytes_read + num_of_bytes_written)/1048576 AS DECIMAL(12, 2)) AS io_in_mb FROM sys.dm_io_virtual_file_stats(NULL, NULL) AS [DM_IO_STATS] GROUP BY database_id) SELECT ROW_NUMBER() OVER(ORDER BY io_in_mb DESC) AS [I/O Rank], [Database Name], io_in_mb AS [Total I/O (MB)], CAST(io_in_mb/ SUM(io_in_mb) OVER() * 100.0 AS DECIMAL(5,2)) AS [I/O Percent] FROM Aggregate_IO_Statistics ORDER BY [I/O Rank] OPTION (RECOMPILE); -- Helps determine which database is using the most I/O resources on the instance
16. 明確的數據庫服務器上所有數據庫的高讀和寫延遲(數據庫文件的IO延遲)
--下面的查詢返回哪個數據庫文件有最大的I/O延遲: -- Calculates average stalls per read, per write, -- and per total input/output for each database file. SELECT DB_NAME(fs.database_id) AS [Database Name], mf.physical_name, io_stall_read_ms, num_of_reads, CAST(io_stall_read_ms/(1.0 + num_of_reads) AS NUMERIC(10,1)) AS [avg_read_stall_ms],io_stall_write_ms, num_of_writes,CAST(io_stall_write_ms/(1.0+num_of_writes) AS NUMERIC(10,1)) AS [avg_write_stall_ms], io_stall_read_ms + io_stall_write_ms AS [io_stalls], num_of_reads + num_of_writes AS [total_io], CAST((io_stall_read_ms + io_stall_write_ms)/(1.0 + num_of_reads + num_of_writes) AS NUMERIC(10,1)) AS [avg_io_stall_ms] FROM sys.dm_io_virtual_file_stats(null,null) AS fs INNER JOIN sys.master_files AS mf WITH (NOLOCK) ON fs.database_id = mf.database_id AND fs.[file_id] = mf.[file_id] ORDER BY avg_io_stall_ms DESC OPTION (RECOMPILE); -- Helps determine which database files on -- the entire instance have the most I/O bottlenecks
17. 查詢指定數據庫中總物理讀最高的查詢以及相關信息(排名前十的)
SELECT TOP 10 t.text , execution_count , statement_start_offset AS stmt_start_offset , sql_handle , plan_handle , total_logical_reads / execution_count AS avg_logical_reads , total_logical_writes / execution_count AS avg_logical_writes , total_physical_reads / execution_count AS avg_physical_reads,t.dbid FROM sys.dm_exec_query_stats AS s CROSS APPLY sys.dm_exec_sql_text(s.sql_handle) AS t --WHERE DB_NAME(t.dbid) = 'AdventureWorks2008R2' ORDER BY avg_physical_reads DESC;
18. 將所有數據庫的恢復模式設置成簡單模式(系統數據庫除外)
USE [master] GO --alter database model set recovery simple with no_wait declare @sqltext varchar(1000), @dbname varchar(500) declare mycursor cursor for select name from sys.databases where database_id >4 open mycursor fetch next from mycursor into @dbname while @@FETCH_STATUS=0 begin print @dbname set @sqltext='ALTER DATABASE ['+@dbname+'] SET RECOVERY SIMPLE WITH NO_WAIT' exec (@sqltext) --print @sqltext fetch next from mycursor into @dbname end close mycursor deallocate mycursor
19. 查看文件組信息
--查看具體指定數據庫的文件組信息 use xxxDB SELECT df.[name], df.physical_name, df.[size], df.growth, fg.[name] [filegroup], fg.is_default FROM sys.database_files df JOIN sys.filegroups fg ON df.data_space_id = fg.data_space_id
20. 判斷表是堆表還是聚集索引表
--通過判斷index_id的值,區分表的類型 --當index_id爲0時,則爲堆表 --當index_id爲1時,則爲聚集索引表 select object_name(a.object_id), case a.index_id when 0 then '堆表' when 1 then '聚集索引表' end table_type from sys.partitions a where a.index_id<2 group by a.object_id,a.index_id
21. 如何正確判斷何時使用堆表和聚集索引表
我們有很多理由去創建一個聚集索引表,而非堆表。那麼最大的理由可能就是:當一個非聚集索引包含的列不能完全符合一條查詢(select)時,執行計劃可通過聚集索引查找,而非通過表掃描的方式。 那麼我們爲什麼會選擇堆表,原因大致就如下2點: 1. 堆表沒有聚集索引,因此堆表可節省索引的磁盤空間 2. 堆表沒有聚集索引,且數據組織是無序的,節省了排序操作,寫入操作更快。 特別注意:在聚集索引索引表上創建分區時,務必檢查sql腳本。若設置的分區函數指定的列不是聚集索引列,將會導致聚集索引的變化(刪除與重建),最終導致表的類型轉換
22. 查看當前實例運行的事務(事務的回話id,運行時長,事務類型等等)
SELECT ST.session_id AS spid, ST.transaction_id AS TransactionID , DB_NAME(DT.database_id) AS DatabaseName , AT.transaction_begin_time AS TransactionStartTime , DATEDIFF(SECOND, AT.transaction_begin_time, GETDATE()) AS TransactionDuration , CASE AT.transaction_type WHEN 1 THEN 'Read/Write Transaction' WHEN 2 THEN 'Read-Only Transaction' WHEN 3 THEN 'System Transaction' WHEN 4 THEN 'Distributed Transaction' END AS TransactionType , CASE AT.transaction_state WHEN 0 THEN 'Transaction Not Initialized' WHEN 1 THEN 'Transaction Initialized & Not Started' WHEN 2 THEN 'Active Transaction' WHEN 3 THEN 'Transaction Ended' WHEN 4 THEN 'Distributed Transaction Initiated Commit Process' WHEN 5 THEN 'Transaction in Prepared State & Waiting Resolution' WHEN 6 THEN 'Transaction Committed' WHEN 7 THEN 'Transaction Rolling Back' WHEN 8 THEN 'Transaction Rolled Back' END AS TransactionState FROM sys.dm_tran_session_transactions AS ST INNER JOIN sys.dm_tran_active_transactions AS AT ON ST.transaction_id = AT.transaction_id INNER JOIN sys.dm_tran_database_transactions AS DT ON ST.transaction_id = DT.transaction_id where ST.is_user_transaction=1 ORDER BY TransactionStartTime go
23. 批量刪除事務(或者聯繫22中事務查看方法進行刪除)
declare @sessionid int ,@sqltxt varchar(max) declare mycursor cursor for select session_id from sys.dm_tran_session_transactions where is_user_transaction=1 open mycursor fetch next from mycursor into @sessionid while @@FETCH_STATUS = 0 begin --print @sessionid set @sqltxt = 'kill '+convert(varchar(5),@sessionid) print @sqltxt exec (@sqltxt) fetch next from mycursor into @sessionid end close mycursor deallocate mycursor
24. 查看sqlserver日誌具體報錯信息(根據錯誤編號以及嚴重性等級)
select * from sys.messages where message_id = 17836 and language_id = 2052 ---在網絡數據包負載中指定的長度與讀取的字節數不匹配;該連接已關閉。請與客戶端庫的供應商聯繫。%1!
25. 查看sqlserver指定表的索引信息
SELECT 索引名稱=a.name ,表名=c.name ,索引字段名=d.name ,索引字段位置=d.colid ,c.status FROM sysindexes a JOIN sysindexkeys b ON a.id=b.id AND a.indid=b.indid JOIN sysobjects c ON b.id=c.id JOIN syscolumns d ON b.id=d.id AND b.colid=d.colid WHERE a.indid NOT IN(0,255) and c.xtype='U' --and c.status>0 --查所有用戶表 AND c.name='GamePay' --查指定表 ORDER BY c.name,a.name,d.name;
26. 查看sqlserver實例上的鎖以及解除鎖
查看被鎖表: select request_session_id spid,OBJECT_NAME(resource_associated_entity_id) tableName from sys.dm_tran_locks where resource_type='OBJECT' spid 鎖表進程 tableName 被鎖表名 解鎖: declare @spid int Set @spid = 57 --鎖表進程 declare @sql varchar(1000) set @sql='kill '+cast(@spid as varchar) exec(@sql)
27. 關閉指定數據庫的連接(正在執行的sql)
USE master go DECLARE @Sql NVARCHAR(max) SET @Sql='' select @Sql=@Sql+'kill '+cast(spid as varchar(50))+';' from sys.sysprocesses where dbid=DB_ID('數據庫名') EXEC(@Sql)