Ich sammle alle 5 Minuten IO_STALLS aus sys.dm_io_virtual_file_stats und mache dann ein Delta, um zu sehen, welche Dateien am meisten von IO betroffen sind.
In einem Zeitraum von 5 Minuten erhalte ich ein Delta von 5826331 ms, was 97 Minuten entspricht.
Ich bin ein wenig verwirrt darüber. Bedeutet dies, dass eine Operation, die vor 97 Minuten begonnen wurde, erst zu diesem Zeitpunkt beendet wurde und daher diese Wartezeit aufzeichnete?
Vielen Dank
Code wie gewünscht hinzugefügt:
/*
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
io_stall
an sich bedeutet nicht zu viel. Wenn Sie in 10 Sekunden 1000 Vorgänge für jeweils 1 Sekunde zum Stillstand gebracht haben, haben Sie 1000 Sekunden Stillstand. Das wären mehr als 16 Minuten Stand in 10 Sekunden. Sie müssen dies mit E / A-Operationen korrelieren. Können Sie Ihre aktuelle Anfrage in Ihrer Frage posten?Antworten:
Frage Kommentar unten eingefügt:
Das Obige ist ein ziemlich gutes Beispiel dafür, wie Sie monumentale und scheinbar übertriebene Zahlen sehen können. An sich
io_stall
bedeutet das eigentlich nichts. Sie müssen den Umfang der E / A-Operationen für diesen kumulativen Stillstand kennen.Anstatt dies zu haben:
Sie müssen den Stall durch E / A-Operationen teilen, um den durchschnittlichen Stall pro E / A (oder pro Lese- oder Schreibzugriff oder nach der gewünschten Granularität) zu erhalten. Mit anderen Worten, meine Empfehlung wäre, Ihre Abfrage so zu ändern, dass sie ungefähr so aussieht:
Und dann benötigen Sie eine zusätzliche Prädikatklausel, um sicherzustellen, dass Sie nicht durch Null teilen:
Grundsätzlich wird der Durchschnitt
io_stall
pro E / A-Vorgang berechnet . Ein Hoch an sichio_stall
könnte einfach eine höhere Arbeitsbelastung bedeuten und nicht unbedingt das Zeichen eines Problems.quelle