SQL Server - 比较 PageSplits/sec 和 Batch Requests/Sec

fra*_*eta 5 sql-server perfmon

我在这里读到(http://www.databasejournal.com/features/mssql/article.php/3932406/Top-10-SQL-Server-Counters-for-Monitoring-SQL-Server-Performance.htm)具有高PageSplits/sec 的值与 BatchRequests/sec 的值相比(在我发布的链接中,参考值为 20%)这是一件坏事,可能是 I/O 问题)。

我尝试使用性能监视器在生产系统中跟踪这两个值,这就是我得到的:

性能监视器

在 RED 中,它是 PageSplits/sec.,另一个是 BatchRequests/sec。

两者的比例都是 1,0(我希望我不会在比较它们时失败)。

有问题吗?

编辑:

由于 Datagod 要求对所涉及的表进行描述,因此我在此处发布了最大表的创建脚本以及可能导致我们性能问题的罪魁祸首。这张表包含大约 350 万行,通常是读密集型和写密集型

/****** Object:  Table [dbo].[e1_tur_ordini_giorno]    Script Date: 11/09/2015 17:31:09 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

SET ANSI_PADDING ON
GO

CREATE TABLE [dbo].[e1_tur_ordini_giorno](
    [id] [varchar](36) NOT NULL CONSTRAINT [DF__e1_tur_ordin__id__5E7FE7D2]  DEFAULT (N'0'),
    [dt_ordine_giorno] [date] NULL CONSTRAINT [DF__e1_tur_or__dt_or__5F740C0B]  DEFAULT (NULL),
    [n_ore] [decimal](10, 2) NULL CONSTRAINT [DF__e1_tur_or__n_ore__60683044]  DEFAULT (NULL),
    [hh_inizio] [varchar](10) NULL CONSTRAINT [DF__e1_tur_or__hh_in__615C547D]  DEFAULT (NULL),
    [hh_fine] [varchar](10) NULL CONSTRAINT [DF__e1_tur_or__hh_fi__625078B6]  DEFAULT (NULL),
    [overload] [int] NULL CONSTRAINT [DF__e1_tur_or__overl__63449CEF]  DEFAULT (NULL),
    [nota] [varchar](255) NULL CONSTRAINT [DF__e1_tur_ord__nota__6438C128]  DEFAULT (NULL),
    [fk_e0_turno] [varchar](36) NULL CONSTRAINT [DF__e1_tur_or__fk_e0__652CE561]  DEFAULT (NULL),
    [fk_e2_per_dipendente] [varchar](36) NULL CONSTRAINT [DF__e1_tur_or__fk_e2__6621099A]  DEFAULT (NULL),
    [fk_e1_tur_orario_servizio] [varchar](36) NULL CONSTRAINT [DF__e1_tur_or__fk_e1__67152DD3]  DEFAULT (NULL),
    [fk_e0_gg_operativo] [varchar](36) NULL CONSTRAINT [DF__e1_tur_or__fk_e0__68FD7645]  DEFAULT (NULL),
    [fk_e0_gg_paghe] [varchar](36) NULL CONSTRAINT [DF__e1_tur_or__fk_e0__69F19A7E]  DEFAULT (NULL),
    [fk_parent_ordine_giorno] [varchar](36) NULL CONSTRAINT [DF__e1_tur_or__fk_pa__6AE5BEB7]  DEFAULT (NULL),
    [fk_e0_tipo_rischio] [varchar](36) NULL CONSTRAINT [DF__e1_tur_or__fk_e0__6BD9E2F0]  DEFAULT (NULL),
    [fk_e0_utente_inserimento] [varchar](36) NULL CONSTRAINT [DF__e1_tur_or__fk_e0__6CCE0729]  DEFAULT (NULL),
    [fk_e0_utente_modifica] [varchar](36) NULL CONSTRAINT [DF__e1_tur_or__fk_e0__6DC22B62]  DEFAULT (NULL),
    [dt_modifica] [datetime2](0) NULL CONSTRAINT [DF__e1_tur_or__dt_mo__6EB64F9B]  DEFAULT (NULL),
    [dt_inserimento] [datetime2](0) NULL CONSTRAINT [DF__e1_tur_or__dt_in__6FAA73D4]  DEFAULT (NULL),
    [fk_e0_prof_nodo] [varchar](36) NULL CONSTRAINT [DF__e1_tur_or__fk_e0__709E980D]  DEFAULT (NULL),
    [riga] [varchar](20) NULL CONSTRAINT [DF__e1_tur_ord__riga__7192BC46]  DEFAULT (NULL),
    [dt_paghe] [date] NULL CONSTRAINT [DF__e1_tur_or__dt_pa__7286E07F]  DEFAULT (NULL),
    [fl_bloccato] [bigint] NULL CONSTRAINT [DF__e1_tur_or__fl_bl__737B04B8]  DEFAULT ((0)),
    [fl_temporaneo] [smallint] NULL CONSTRAINT [DF__e1_tur_or__fl_te__746F28F1]  DEFAULT ((0)),
    [tipo_riga] [varchar](12) NULL CONSTRAINT [DF__e1_tur_or__tipo___75634D2A]  DEFAULT (N'N'),
    [hh_ordinarie] [float] NULL CONSTRAINT [DF__e1_tur_or__hh_or__76577163]  DEFAULT ((0)),
    [tipo_modifica] [varchar](12) NULL CONSTRAINT [DF__e1_tur_or__tipo___774B959C]  DEFAULT (N'N'),
    [fk_e1_tur_servizio] [varchar](36) NULL CONSTRAINT [DF__e1_tur_or__fk_e1__783FB9D5]  DEFAULT (NULL),
    [codice_importazione] [varchar](45) NULL CONSTRAINT [DF__e1_tur_or__codic__7933DE0E]  DEFAULT (NULL),
    [fk_e1_tur_testata] [varchar](36) NULL CONSTRAINT [DF__e1_tur_or__fk_e1__7A280247]  DEFAULT (NULL),
    [fl_annullato] [smallint] NULL CONSTRAINT [DF__e1_tur_or__fl_an__7B1C2680]  DEFAULT ((0)),
    [fl_compensativo] [smallint] NULL CONSTRAINT [DF__e1_tur_or__fl_co__7C104AB9]  DEFAULT ((0)),
    [descrizione] [varchar](255) NULL,
    [fl_recupero] [tinyint] NULL,
    [fk_e0_segmento_dip] [varchar](36) NULL,
    [fl_confermato] [tinyint] NULL CONSTRAINT [DF_e1_tur_ordini_giorno_fl_confermato]  DEFAULT ((0)),
    [fk_e1_tur_pian_reperibilita] [varchar](36) NULL,
    [dt_competenza] [date] NULL,
    [fl_scavallo] [tinyint] NULL,
CONSTRAINT [PK_e1_tur_ordini_giorno_id] PRIMARY KEY CLUSTERED 
(
    [id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO

ALTER TABLE [dbo].[e1_tur_ordini_giorno]  WITH CHECK ADD  CONSTRAINT [e1_tur_ordini_giorno$FK_e1_tur_ordini_giorno_1] FOREIGN KEY([fk_e0_utente_inserimento])
REFERENCES [dbo].[users] ([id])
GO

ALTER TABLE [dbo].[e1_tur_ordini_giorno] CHECK CONSTRAINT [e1_tur_ordini_giorno$FK_e1_tur_ordini_giorno_1]
GO

ALTER TABLE [dbo].[e1_tur_ordini_giorno]  WITH CHECK ADD  CONSTRAINT [e1_tur_ordini_giorno$FK_e1_tur_ordini_giorno_10] FOREIGN KEY([fk_e0_gg_paghe])
REFERENCES [dbo].[e0_conf_gg_paghe] ([id])
GO

ALTER TABLE [dbo].[e1_tur_ordini_giorno] CHECK CONSTRAINT [e1_tur_ordini_giorno$FK_e1_tur_ordini_giorno_10]
GO

ALTER TABLE [dbo].[e1_tur_ordini_giorno]  WITH CHECK ADD  CONSTRAINT [e1_tur_ordini_giorno$FK_e1_tur_ordini_giorno_11] FOREIGN KEY([fk_e1_tur_servizio])
REFERENCES [dbo].[e1_tur_servizi] ([id])
GO

ALTER TABLE [dbo].[e1_tur_ordini_giorno] CHECK CONSTRAINT [e1_tur_ordini_giorno$FK_e1_tur_ordini_giorno_11]
GO

ALTER TABLE [dbo].[e1_tur_ordini_giorno]  WITH CHECK ADD  CONSTRAINT [e1_tur_ordini_giorno$FK_e1_tur_ordini_giorno_12] FOREIGN KEY([fk_e1_tur_testata])
REFERENCES [dbo].[e1_tur_ordini_giorno_testata] ([id])
GO

ALTER TABLE [dbo].[e1_tur_ordini_giorno] CHECK CONSTRAINT [e1_tur_ordini_giorno$FK_e1_tur_ordini_giorno_12]
GO

ALTER TABLE [dbo].[e1_tur_ordini_giorno]  WITH CHECK ADD  CONSTRAINT [e1_tur_ordini_giorno$FK_e1_tur_ordini_giorno_2] FOREIGN KEY([fk_e0_utente_modifica])
REFERENCES [dbo].[users] ([id])
GO

ALTER TABLE [dbo].[e1_tur_ordini_giorno] CHECK CONSTRAINT [e1_tur_ordini_giorno$FK_e1_tur_ordini_giorno_2]
GO

ALTER TABLE [dbo].[e1_tur_ordini_giorno]  WITH CHECK ADD  CONSTRAINT [e1_tur_ordini_giorno$FK_e1_tur_ordini_giorno_3] FOREIGN KEY([fk_e0_prof_nodo])
REFERENCES [dbo].[e0_prof_nodi] ([id])
GO

ALTER TABLE [dbo].[e1_tur_ordini_giorno] CHECK CONSTRAINT [e1_tur_ordini_giorno$FK_e1_tur_ordini_giorno_3]
GO

ALTER TABLE [dbo].[e1_tur_ordini_giorno]  WITH CHECK ADD  CONSTRAINT [e1_tur_ordini_giorno$FK_e1_tur_ordini_giorno_4] FOREIGN KEY([fk_e0_turno])
REFERENCES [dbo].[e0_conf_turni] ([id])
GO

ALTER TABLE [dbo].[e1_tur_ordini_giorno] CHECK CONSTRAINT [e1_tur_ordini_giorno$FK_e1_tur_ordini_giorno_4]
GO

ALTER TABLE [dbo].[e1_tur_ordini_giorno]  WITH CHECK ADD  CONSTRAINT [e1_tur_ordini_giorno$FK_e1_tur_ordini_giorno_5] FOREIGN KEY([fk_e2_per_dipendente])
REFERENCES [dbo].[e2_per_dipendenti] ([id])
GO

ALTER TABLE [dbo].[e1_tur_ordini_giorno] CHECK CONSTRAINT [e1_tur_ordini_giorno$FK_e1_tur_ordini_giorno_5]
GO

ALTER TABLE [dbo].[e1_tur_ordini_giorno]  WITH CHECK ADD  CONSTRAINT [e1_tur_ordini_giorno$FK_e1_tur_ordini_giorno_6] FOREIGN KEY([fk_e1_tur_orario_servizio])
REFERENCES [dbo].[e1_tur_orari_servizi] ([id])
GO

ALTER TABLE [dbo].[e1_tur_ordini_giorno] CHECK CONSTRAINT [e1_tur_ordini_giorno$FK_e1_tur_ordini_giorno_6]
GO

ALTER TABLE [dbo].[e1_tur_ordini_giorno]  WITH CHECK ADD  CONSTRAINT [e1_tur_ordini_giorno$FK_e1_tur_ordini_giorno_7] FOREIGN KEY([fk_e0_gg_operativo])
REFERENCES [dbo].[e0_conf_gg_operativi] ([id])
GO

ALTER TABLE [dbo].[e1_tur_ordini_giorno] CHECK CONSTRAINT [e1_tur_ordini_giorno$FK_e1_tur_ordini_giorno_7]
GO

ALTER TABLE [dbo].[e1_tur_ordini_giorno]  WITH CHECK ADD  CONSTRAINT [e1_tur_ordini_giorno$FK_e1_tur_ordini_giorno_8] FOREIGN KEY([fk_parent_ordine_giorno])
REFERENCES [dbo].[e1_tur_ordini_giorno] ([id])
GO

ALTER TABLE [dbo].[e1_tur_ordini_giorno] CHECK CONSTRAINT [e1_tur_ordini_giorno$FK_e1_tur_ordini_giorno_8]
GO

ALTER TABLE [dbo].[e1_tur_ordini_giorno]  WITH CHECK ADD  CONSTRAINT [e1_tur_ordini_giorno$FK_e1_tur_ordini_giorno_9] FOREIGN KEY([fk_e0_tipo_rischio])
REFERENCES [dbo].[e0_decod_tipi_rischi] ([id])
GO

ALTER TABLE [dbo].[e1_tur_ordini_giorno] CHECK CONSTRAINT [e1_tur_ordini_giorno$FK_e1_tur_ordini_giorno_9]
GO

ALTER TABLE [dbo].[e1_tur_ordini_giorno]  WITH CHECK ADD  CONSTRAINT [FK_e1_tur_ordini_giorno_e0_prof_nodi] FOREIGN KEY([fk_e0_segmento_dip])
REFERENCES [dbo].[e0_prof_nodi] ([id])
GO

ALTER TABLE [dbo].[e1_tur_ordini_giorno] CHECK CONSTRAINT [FK_e1_tur_ordini_giorno_e0_prof_nodi]
GO

ALTER TABLE [dbo].[e1_tur_ordini_giorno]  WITH CHECK ADD  CONSTRAINT [FK_e1_tur_ordini_giorno_e1_tur_pian_reperibilita] FOREIGN KEY([fk_e1_tur_pian_reperibilita])
REFERENCES [dbo].[e1_tur_pian_reperibilita] ([id])
GO

ALTER TABLE [dbo].[e1_tur_ordini_giorno] CHECK CONSTRAINT [FK_e1_tur_ordini_giorno_e1_tur_pian_reperibilita]
GO
Run Code Online (Sandbox Code Playgroud)

然后这里有两个性能监视器的屏幕截图(虽然在不同的时刻拍摄),我首先选择 batchRequests/sec 然后选择 PageSplits/sec

批处理请求数/秒

分页/秒

dat*_*god 1

有问题吗?这取决于你的定义。发生页面拆分是因为 SQL 将记录插入到已满的页面中。整页非常适合阅读,因为数据密集。插入需要将该页面分成两部分,每一页都占 50%。然后将新记录插入到适当的新页面中。

正如您可以想象的那样,这比仅仅将记录添加到具有足够空间的现有页面需要更多的 I/O。

为什么会出现页面分裂?检查作为插入目标的表。数据在物理上是如何排序的?是否存在聚集索引,如果存在,它是什么数据类型?

同样,只有当前系统遇到性能问题或者您打算扩展时,这才是真正的问题。

请发布表的 DDL 以及索引,我将进一步评论。

进一步评论

根据对表的分析,ID 键可能是某种类型的 GUID。本质上,GUID 是随机的。对随机值进行聚类会导致页面分裂。您告诉 SQL Server 对随机生成的值进行物理排序。

如果这些 GUID 不是按顺序生成的,这对性能来说是很糟糕的。

对于聚集索引来说,这是一个相对较大的值,并且当聚集索引成为每个非聚集索引的一部分时,会放大性能问题。