Questions tagged «fragmentation»

当索引的页面中基于键值的逻辑顺序与数据文件中的物理顺序不匹配时,就会存在碎片。

3
重建并重新索引所有内容后,为什么我的数据库仍然碎片化?
我有一个数据库,我试图通过运行以下T-SQL对所有表进行碎片整理: SELECT 'ALTER INDEX all ON ' + name + ' REORGANIZE;' + CHAR(10) + 'ALTER INDEX all ON ' + name + ' REBUILD;' FROM sys.tables 然后将输出复制并粘贴到新的查询窗口中并运行它。我没有任何错误,但是仍然有碎片。我也尝试单独运行两个命令,但仍然有碎片。注意:REORGANIZE Aaron 已使我意识到这是不必要的,并且我知道可以使用动态sql来自动执行此操作。 我运行此命令以确定我仍然有碎片: SELECT * FROM sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL , NULL, NULL) WHERE avg_fragmentation_in_percent > 0 我得到: database_id object_id index_id partition_number …


4
什么是对表进行大的更改更好的方法:每次都删除或插入,或者存在UPDATE?
我正在做一个项目,每天需要在一张桌子中更改约36000条记录。我想知道什么会更好地执行: 删除行并插入新行,或者 更新现有的行 对我来说,删除所有行并插入新行比较容易,但是如果这将使表和索引碎片化并影响性能,那么我希望尽可能进行更新并仅在必要时删除/插入。 这将是每晚的服务,我不希望提高流程本身的速度。我更关注针对该表的查询的性能,总体而言,我已经有8900万条记录,以及该每晚过程将如何影响它。 我应该删除/插入记录,还是应该在每晚过程中更新现有记录(如果可能)?

2
可以对SQL Server系统表进行碎片整理吗?
我们有几个数据库,在其中创建和删除了大量表。据我们所知,SQL Server不会对系统基表进行任何内部维护,这意味着它们随着时间的流逝会变得非常零散,并且大小会膨胀。这给缓冲池造成了不必要的压力,并且还负面影响了操作的性能,例如计算数据库中所有表的大小。 有没有人建议尽量减少这些核心内部表上的碎片?一个显而易见的解决方案可以避免创建太多表(或在tempdb中创建所有临时表),但是出于这个问题的目的,我们可以说应用程序没有这种灵活性。 编辑:进一步的研究显示了这个悬而未决的问题,该问题看起来密切相关,并且表明可以选择某种形式的手动维护ALTER INDEX...REORGANIZE。 初步研究 有关这些表的元数据可以在以下位置查看sys.dm_db_partition_stats: -- The system base table that contains one row for every column in the system SELECT row_count, (reserved_page_count * 8 * 1024.0) / row_count AS bytes_per_row, reserved_page_count/128. AS space_mb FROM sys.dm_db_partition_stats WHERE object_id = OBJECT_ID('sys.syscolpars') AND index_id = 1 -- row_count: 15,600,859 -- …

3
PostgreSQL初始数据库大小
我的问题分为两部分。 有没有一种方法可以在PostgreSQL中指定数据库的初始大小? 如果没有,当数据库随着时间增长时如何处理碎片? 我最近从MSSQL迁移到Postgres,在创建数据库时我们在MSSQL世界中所做的一件事是指定数据库和事务日志的初始大小。这样可以减少碎片并提高性能,尤其是如果事先知道数据库的“正常”大小时。 数据库的性能随着大小的增长而下降。例如,我要处理的工作量通常需要10分钟。随着数据库的增长,这个时间增加了。进行VACUUM,VACUUM FULL和VACUUM FULL ANALYZE似乎无法解决问题。解决性能问题的方法是停止数据库,对驱动器进行碎片整理,然后进行VACUUM FULL ANALYZE,将测试的性能恢复到最初的10分钟。这使我怀疑碎片化是导致我疼痛的原因。 我在Postgres中找不到任何有关保留表空间/数据库空间的引用。我使用的术语错误,因此一无所获,或者在Postgres中有另一种缓解文件系统碎片的方法。 有指针吗? 解决方案 提供的答案有助于确认我开始怀疑的地方。PostgreSQL将数据库存储在多个文件中,这使数据库可以增长而无需担心碎片。默认行为是将这些文件与表数据一起打包到边缘,这对很少更改的表有好处,但对经常更新的表不利。 PostgreSQL利用MVCC提供对表数据的并发访问。在此方案下,每次更新都会创建已更新行的新版本(可以通过时间戳或版本号,谁知道呢?)。旧数据不会立即删除,但会标记为删除。实际删除发生在执行VACUUM操作时。 这与填充因子有何关系?表格默认填充因子100完全填满了表格页面,这又意味着表格页面中没有空间来容纳更新的行,即,更新的行将与原始行放置在不同的表格页面中。如我的经验所示,这对性能不利。由于汇总表的更新非常频繁(最高1500行/秒),因此我选择将填充因子设置为20,即表的20%用于插入的行数据,而80%用于更新数据。尽管这看起来可能过多,但为更新的行保留的大量空间意味着更新的行与原始行位于同一页面内,并且在自动清理守护程序运行以删除过时的行时,表页面未满。 为了“修复”我的数据库,我做了以下工作。 将摘要表的填充因子设置为20。您可以在创建时通过将参数传递给CREATE TABLE或在事后通过ALTER TABLE来实现。我发出了以下plpgsql命令:ALTER TABLE "my_summary_table" SET (fillfactor = 20); 发出VACUUM FULL,因为这将写入表文件的全新版本,因此,暗含了使用新的填充因子写入新的表文件的情况。 重新运行测试,即使数据库足够大以容纳数百万行,我也看不到性能下降。 TL; DR-不是文件碎片造成的,而是表空间碎片造成的。通过调整表格的填充因子以适合您的特定用例,可以缓解这种情况。

2
MySQL索引维护
我做了很多有关如何在MySQL中维护索引以防止碎片并以某种方式优化查询执行的研究。 我熟悉该公式,该公式可计算表的最大可用空间与数据和索引使用的空间之间的比率。 但是我的主要问题仍然没有答案。也许这是由于我熟悉SQL Server中的索引维护,并且我倾向于认为在MySQL中它应该在某种程度上相似。 在SQL Server中,您可以具有多个索引,并且每个索引可以具有不同级别的碎片。然后,您可以选择一个并在该特定索引中执行“ REORGANIZE”或“ REBUILD”操作,而不会影响其余的索引。 据我所知,没有这种“表碎片”,并且SQL Server没有提供任何工具来修复“表碎片”。它确实提供了检查索引碎片的工具(可以理解为索引碎片使用的工具,例如索引所使用的页数与该页的填充度和连续性之间的比率),以及内部和外部碎片。 至少对于我来说,所有这些都是很容易理解的。 现在,当轮到在MySQL中维护索引时,如上所述,仅存在“表碎片”的概念。 MySQL中的一个表可以有多个索引,但是当我用那个著名的公式检查“碎片率”时,我看不到每个索引的碎片,而是整个表。 当我想优化MySQL中的索引时,我不选择要操作的特定索引(如SQL Server中一样)。相反,我在整个表中执行“ OPTIMIZE”操作,这大概会影响所有索引。 当在MySQL中优化表时,数据+索引使用的空间与整个空间之间的比率将减小,这表明硬盘驱动器中进行了某种物理重组,这意味着物理空间的减少。但是,索引碎片不仅与物理空间有关,而且与由于插入和更新而随时间变化的树的结构有关。 最后,我在InnoDB / MySQL中得到了一个表。该表具有300万条记录,105列和55个索引。它是1.5GB(不包括索引),后者是2.1GB。 每天都要对该表进行数千次点击以进行更新和插入(实际上,我们并未删除记录)。 该表已经创建多年,我可以肯定没有人维护索引。 我原本希望在那里找到一个巨大的碎片,但是当我按照规定执行碎片计算时 free_space / (data_length + index_length) 事实证明,我的碎片只有0.2%。恕我直言,这是非常不现实的。 因此,主要问题是: 如何检查MySQL中特定索引的碎片,而不是整个表格 OPTIMIZE TABLE是否像SQL Server一样实际修复了索引的内部/外部碎片? 当我在MySQL中优化表时,它实际上会重建表上的所有索引吗? 认为减少索引的物理空间(而不重建树本身)实际上转化为更好的性能是否现实?

2
如何防止每日索引碎片达到99%
我有一个供100.000名玩家使用的高分桌,每天被插入2次,每位玩家有一条记录。最终,该表中索引的索引碎片为99%。有没有办法通过调整设置来防止这种情况? CREATE TABLE HighScore( [id] [int] IDENTITY(1,1) NOT NULL, [user] [int] NULL, [player] [int] NULL, [round] [tinyint] NULL, [group] [int] NULL, [rank] [int] NULL, [delta] [int] NULL, [roundpoints] [int] NULL, [totalpoints] [int] NULL, PRIMARY KEY CLUSTERED ( [id] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS …

1
使用MoveFile API对SQL Server数据和日志文件进行碎片整理
我的雇主正在考虑部署使用Windows MoveFile API对打开的文件进行碎片整理的NTFS碎片整理软件。它将部署到运行2005-2012年的SQL版本以及2003和2008 R2的Windows版本的数千台SQL Server服务器中。如果重要的话,我正在谈论的产品是PerfectDisk,但我相信有类似的程序也可以以相同的方式工作。 除了偶尔的I / O性能问题外,到目前为止,测试还没有引发很多问题,这不足为奇,可以通过重新计划和调整碎片整理来解决。但是,我更担心数据损坏的风险。 这里有没有人有在数据库服务器上的生产环境中运行此类软件的经验?您是否遇到任何数据损坏? 尽管找不到任何确凿的证据表明存在问题,但我对此感到不安。 感谢您的任何答复。 编辑添加:幸运的是,这个可怕的想法被遗忘了,可能部分是由于我给出的一些警告。

2
连续处理时索引碎片
SQL Server 2005 我需要能够连续处理900M记录表中的约350M记录。在处理过程中,我用来选择要处理的记录的查询变得非常分散,我需要停止处理以重建索引。伪数据模型和查询... /**************************************/ CREATE TABLE [Table] ( [PrimaryKeyId] [INT] IDENTITY(1,1) NOT NULL PRIMARY KEY CLUSTERED, [ForeignKeyId] [INT] NOT NULL, /* more columns ... */ [DataType] [CHAR](1) NOT NULL, [DataStatus] [DATETIME] NULL, [ProcessDate] [DATETIME] NOT NULL, [ProcessThreadId] VARCHAR (100) NULL ); CREATE NONCLUSTERED INDEX [Idx] ON [Table] ( [DataType], …

1
如何降低SQL Server中的HEAP碎片?
我最近发现,一个堆表的碎片超过70%。所以我决定做一个 ALTER TABLE dbo.myTable REBUILD 有趣的是,事后我有20%的支离破碎。从那以后,在那张桌子上没有写任何东西。因此,我决定再进行一次重建。 第二次后,桌子上的帽子碎裂了50%,甚至更多! 我真的不明白怎么会这样...

2
重建-聚集索引,表或两者?
我在任何地方都找不到确切的资源,因此希望一位专家可以在这里给我答案。 我有一个很大的表,我们必须在其中添加一列。聚集索引非常分散,我想做一个ALTER INDEX REBUILD清理它。 我通常ALTER TABLE REBUILD在更改列时也会执行一次,因为这会清除该操作中的所有指针或拆分。 因为我们在谈论聚集索引,本质上就是表,我是否需要同时做这两个事情? 我怀疑ALTER INDEX REBUILD集群中的不会更新遗嘱的所有内容ALTER TABLE,但是我也担心ALTER TABLE不会清理索引碎片。

6
索引重建时间是否取决于碎片级别?
重建索引所需的时间是否取决于碎片级别? 如果重建相同索引的40%碎片索引需要1分钟,重建80%碎片索引大约需要2分钟吗? 我要求的是执行所需操作所需的RUNTIME(例如,以秒为单位),而不是关于在特定情况下需要执行哪些操作。我知道应该进行索引重组或重建/统计更新时的基本最佳实践。 这个问题不问关于REORG以及REORG和REBUILD之间的区别。 背景:由于设置了不同的索引维护作业(每个晚上,周末工作量较大……),我想知道是否应该对低中级零散的索引更好地执行每日“轻度”离线索引维护作业,以保持关闭时间很小-甚至没有关系,在80%碎片索引上进行重建可能需要与在40%碎片索引上进行相同操作的时间相同。 我遵循了建议,并试图找出自己正在发生的事情。我的实验设置:在没有其他操作且未被任何人或其他任何人使用的测试服务器上,我在uniqueidentifier主键列上创建了带有聚簇索引的表,其中包含一些其他列和不同的数据类型[2数字,9日期时间和2 varchar(1000)]并简单地添加行。对于提出的测试,我增加了约305,000行。 然后,我使用了一条更新命令,并随机更新了对整数值进行过滤的行范围,并使用变化的字符串值更改了VarChar列之一以创建碎片。之后,我检查中的当前avg_fragmentation_in_percent水平sys.dm_db_index_physical_stats。每当为基准创建“新”碎片时,都会将此值(包括该physical_page_count值)添加到下图所组成的录音中。 然后我跑了出来:Alter index ... Rebuild with (online=on); 并CPU time通过STATISTICS TIME ON录音来抓取。 我的期望:我期望至少看到一种线性曲线的指示,该线性曲线显示碎片水平和cpu时间之间的依赖关系。 不是这种情况。我不确定此程序是否真的适合取得良好效果。也许行数/页面数太少? 但是结果表明,我最初的问题的答案肯定是“ 否”。看起来SQL Server重建索引所需的cpu时间既不依赖于碎片级别,也不依赖于基础索引的页数。 第一张图表显示了与先前的碎片级别相比,重建索引所需的cpu时间。如您所见,平均线是相对恒定的,碎片与所需的cpu时间之间根本没有关系。 为了尊重更新后索引页数变化可能会影响重建的时间的影响,我计算了FRAGMENTATION LEVEL * PAGES COUNT并在第二张图表中使用了该值,该图表显示了所需cpu时间的关系以及碎片和页数。 如您所见,即使页面数有所变化,这也并不表示重建所需的时间受碎片影响。 在做出这些陈述之后,我想我的程序一定是错误的,因为重建一个庞大且高度分散的索引所需的cpu时间可能仅受行数的影响-我并不真正相信这一理论。 因此,因为我确实非常想立即发现这一点,所以欢迎任何进一步的评论和建议。

1
SQL Server中的B树节点拆分策略可单调增加价值
考虑一个将始终单调增加的值的B树索引,例如IDENTITY类型的列。使用传统的B树实现,每当一个节点满时,它将被拆分50%/ 50%,最后我们得到一个B树,其中几乎所有节点都只有50%满。 我知道Oracle发现何时值会不断增加,在这种情况下,Oracle会执行90%/ 10%的拆分。这样,(几乎)所有节点都将充满90%的数据,对于这些非常常见的情况,页面利用率要高得多。 我无法在SQL Server中找到类似功能的文档。但是,我进行了两个实验,分别在索引中插入了N个随机整数和N个连续整数。前一种情况使用了更多的页面,而后者则使用了更多页面。 SQL Server是否提供类似的功能?如果是这样:您能指出我一些有关此功能的文档吗? 更新: 通过下面提供的实验,叶节点似乎保持未分裂状态,内部节点分裂了50%/ 50%。这使得递增键上的B树比随机键上的树更紧凑。但是,Oracle提出的90%/ 10%的方法甚至更好,我仍然在寻找一些官方文档来验证实验中看到的行为。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.