Tom*_*Tom 9 performance sql-server
我每 5 分钟从 sys.dm_io_virtual_file_stats 收集 IO_STALLS,然后进行增量以查看哪些文件受 IO 影响最大。
在一个 5 分钟的时间内,我得到了 5826331 毫秒的增量,即 97 分钟。
我对此有点困惑,这是说 97 分钟前开始的操作仅在那时完成并因此记录了等待时间?
谢谢
根据要求添加代码:
/*
USE [SysDBA]
GO
*/
/****** Object: Table [dbo].[DISKIOPS] Script Date: 04/07/2013 11:40:15 ******/
/*
DROP TABLE [dbo].[DISKIOPS]
GO
*/
--Create the table
/****** Object: Table [dbo].[DISKIOPS] Script Date: 04/07/2013 11:40:15 ******/
/*
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[DISKIOPS](
[IO_STALL] [bigint] NULL,
[IO_STALL_READ_MS] [bigint] NULL,
[IO_STALL_WRITE_MS] [bigint] NULL,
[NUM_OF_READS] [bigint] NULL,
[NUM_OF_WRITES] [bigint] NULL,
[SIZE_ON_DISK_MB] [bigint] NULL,
[DBNAME] [varchar](max) NULL,
[NAME] [varchar](max) NULL,
[FILE_ID] [int] NULL,
[DB_FILE_TYPE] [varchar](max) NULL,
[DISK] [varchar](max) NULL,
[FILE_LOCATION] [varchar](max) NULL,
[TIMESTAMP] [datetime] NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
*/
--Capture IO information from DMV and query to find deltas over time.
/*
USE [SysDBA]
GO
INSERT INTO [dbo].[DISKIOPS]
([IO_STALL]
,[IO_STALL_READ_MS]
,[IO_STALL_WRITE_MS]
,[NUM_OF_READS]
,[NUM_OF_WRITES]
,[SIZE_ON_DISK_MB]
,[DBNAME]
,[NAME]
,[FILE_ID]
,[DB_FILE_TYPE]
,[DISK]
,[FILE_LOCATION]
,[TIMESTAMP])
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.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,
b.physical_name AS File_location,
GETDATE() AS Timestamp
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
GO
*/
DECLARE @File_Name VARCHAR(8000),
@Disk VARCHAR(5)
SET @File_Name = 'DBTEST'
SET @Disk = 'I:'
--Code to pull out deltas between collected IO stats.
;WITH IOPS ([IO_STALL]
,[IO_STALL_READ_MS]
,[IO_STALL_WRITE_MS]
,[NUM_OF_READS]
,[NUM_OF_WRITES]
,[SIZE_ON_DISK_MB]
,[DBNAME]
,[NAME]
,[FILE_ID]
,[DB_FILE_TYPE]
,[DISK]
,[FILE_LOCATION]
,[TIMESTAMP]
,[ROW])
AS
(
SELECT *, ROW_NUMBER() OVER (PARTITION BY FILE_LOCATION ORDER BY TIMESTAMP DESC) AS [ROW]
FROM dbo.DISKIOPS
)
SELECT MAX([IO2].[IO_STALL] - [IO1].[IO_STALL])
FROM IOPS IO1 JOIN IOPS IO2 ON IO1.ROW = (IO2.ROW+1)
WHERE IO1.NAME = IO2.NAME
AND IO1.Disk = @Disk
Run Code Online (Sandbox Code Playgroud)
Tho*_*ger 11
问题评论粘贴在下面:
io_stall本身并不意味着太多。如果在 10 秒内您有 1000 次操作每个暂停 1 秒,那么您将有 1000 秒的暂停。这将是 10 秒内超过 16 分钟的停顿。您需要将其与 IO 操作相关联...
上面是一个很好的例子,说明了如何看到不朽的和看似夸张的数字。就其本身而言,io_stall并不意味着什么。您需要知道该累积停顿的 I/O 操作规模。
而不是有这个:
SELECT MAX([IO2].[IO_STALL] - [IO1].[IO_STALL])
FROM IOPS IO1 JOIN IOPS IO2 ON IO1.ROW = (IO2.ROW+1)
...
Run Code Online (Sandbox Code Playgroud)
您需要将停顿除以 I/O 操作以获得每个 I/O(或每个读取、或写入,或您正在寻找的任何粒度)的平均停顿。换句话说,我的建议是将您的查询修改为如下所示:
SELECT
MAX(([IO2].[IO_STALL] - [IO1].[IO_STALL]) / (IO2.NUM_OF_READS + IO2.NUM_OF_WRITES - IO1.NUM_OF_READS - IO1.NUM_OF_WRITES))
FROM IOPS IO1 JOIN IOPS IO2 ON IO1.ROW = (IO2.ROW+1)
Run Code Online (Sandbox Code Playgroud)
然后你需要有一个额外的谓词子句来确保你没有被零除:
...
WHERE IO1.NAME = IO2.NAME
and (IO2.NUM_OF_READS + IO2.NUM_OF_WRITES - IO1.NUM_OF_READS - IO1.NUM_OF_WRITES) > 0
AND IO1.Disk = @Disk
Run Code Online (Sandbox Code Playgroud)
这基本上是计算每个 I/O 操作的平均值io_stall。就其本身而言,高io_stall可能只是意味着更高的工作量,而不一定是问题的迹象。
| 归档时间: |
|
| 查看次数: |
4376 次 |
| 最近记录: |