我在这里读到(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
然后是性能监视器的另外两个屏幕截图(虽然是在不同的时刻拍摄的),我首先选择了 batchRequests/sec 然后是 PageSplits/sec
有问题吗?这取决于你的定义。发生页面拆分是因为 SQL 将记录插入到已经满的页面中。整页非常适合阅读,因为数据密集。插入要求将该页一分为二,每页占满 50%。然后将新记录插入到适当的新页面中。
可以想象,这需要更多的 I/O,而不是仅仅将记录添加到具有足够空间的现有页面。
为什么会发生页面拆分?检查作为插入目标的表。数据是如何物理排序的?聚集索引是否存在,如果存在,它是什么数据类型?
同样,只有当当前系统遇到性能问题或者您打算扩展时,这才是真正的问题。
请将表的 DDL 与索引一起发布,我将进一步评论。
进一步评论
根据对您的表的分析,ID 键可能是某种类型的 GUID。从本质上讲,GUID 是随机的。对随机值进行聚类会导致页面拆分。您告诉 SQL Server 对随机生成的值进行物理排序。
如果这些 GUID 不是按顺序生成的,这对性能来说是很糟糕的。
对于聚簇索引而言,这是一个相对较大的值,并且随着聚簇索引成为每个非聚簇索引的一部分,会放大性能问题。