我使用 MongoDB 3.6 我的收藏中有大量碎片。一个集合 300+ GB。WiredTiger 是存储引擎。
我知道它对操作系统不利并且浪费了很多空间。如果我们使用 MMAP 引擎,这也会影响内存。但我不知道碎片如何影响WiredTiger?
我使用 MongoDB 3.6 我的收藏中有大量碎片。一个集合 300+ GB。WiredTiger 是存储引擎。
我知道它对操作系统不利并且浪费了很多空间。如果我们使用 MMAP 引擎,这也会影响内存。但我不知道碎片如何影响WiredTiger?
就我在研究中看到的而言,碎片唯一的东西是索引,SQL 中的其他对象无法碎片化。
我必须跟踪多个数据库中的碎片,理解我只检查索引碎片是否正确?任何其他对象都可以碎片吗?需要检查吗?
我尝试使用 innodb-defragment=1 https://mariadb.com/kb/en/library/defragmenting-innodb-tablespaces/对表进行碎片整理
但这是一次糟糕的经历: - 锁定表 - 没有好的碎片整理结果(表上始终没有数据)
所以我使用 percona-tools https://www.percona.com/doc/percona-toolkit/LATEST/pt-online-schema-change.html
并得到一个很好的结果,没有锁,也没有更多的数据在桌子上。(但需要磁盘空间来复制表)
但是第一种方法有什么问题?
更新 :
有什么方法可以检查表或索引是否已经碎片化?
如何检查表是否碎片?
如何检查索引是否碎片?
我搜索了谷歌,但没有得到满意的答案。我得到了一些点,比如解释计划、表碎片、索引重建等。但是我们的第一步应该是什么,应该如何解决。我们如何一步一步地解决问题?
我们有一个 Azure SQL 数据库层 S4(200 DTU),里面有一个大表
当我运行“alter index rebuild ...”语句时,大约需要 18 分钟才能完成
这个特定的非聚集索引大小为 5 Gb,在重建的 18 分钟内,它占用了该数据库可用的所有 100% DTU 当然,这会影响其他尝试使用该数据库的应用程序
问题:
How can we limit available resources for a given session that runs a rebuild ?
Say, we want to make it use only 50%-60% of Database's DTUs, but not 100%
这在 Azure SQL 数据库上可行吗?
问候,
我有几个供应商数据库,其中大部分 (99%) 表都聚集在 GUID 上。目前我们每个周末都在重建表格。此时大多数表的碎片化程度达到 80% 或更多。
除了这种无休止的循环,我们不重建会更好吗?
更频繁地更新静态信息而不是重建索引会更有益吗?
我已经阅读了 Brent Ozar 的Stop Worrying About SQL Server Fragmentation,但它并没有真正回答我的问题。我希望有一篇更完整的文章,并且可能是最近更新的文章。
我尽量不这样做,因为我知道这是没有必要的。如果有助于更好地了解我的情况,请从 Brent 的博客再次查看本文的开头部分。我希望有一个包含文章和用例的正式计划,以便在进行更改之前向管理层提出建议并阅读适当的文档。
我正在为我们的生产数据库设计一个新的维护计划。我们唯一的维护是每周重建。有几个(30 多个)数据库都在 700 GB-1.2 TB 左右。表的最大尺寸范围为 100-300 GB。
我希望有一个更好的维护计划,最终提供更好的性能。
我最近发现一个堆表有超过 70% 的碎片。所以我决定做一个
ALTER TABLE dbo.myTable REBUILD
有趣的是,之后我有 20% 的碎片化。从那以后,那张桌子上就再也没有写过字了。所以我决定再做一次重建。
在第二次之后,表帽 50% 的碎片变得如此之多! 我真的不明白这怎么会发生......
据我所知,当表具有聚簇索引时,在针对某些数据对表进行范围扫描时会发生这种情况:
先找出较低的范围,追踪到它所在的叶子节点,然后通过下一页指针逐页遍历叶子级别只要该页中的最大值小于范围扫描的较大值即可健康)状况。
一旦到达最后一行超过该页面的页面,该过程就会停止,在该页面内进行二进制搜索以找出该记录,并返回到目前为止找到的所有记录。
如果页面不在内存中,逐页调出可能是昂贵的 I/O 操作,因此为了缓解这种情况,预读扫描由父页面在上一级完成,这样当进程前进到一个叶级页面来验证它,它已经被父级页面之一带到内存中。
我正在观看一些 SQL Server 教程视频,其中说如果在叶级别存在逻辑碎片,那么物理页面顺序与逻辑页面顺序不一致,预读扫描失败并且数据库被强制执行检索所有页面的完整 I/O 操作。
有人能告诉我为什么吗?为什么物理顺序很重要?整个遍历不就是通过叶级页面的下一页指针逻辑遍历完成的吗?
逻辑碎片对预读扫描到底有什么影响?
使用 SQL Server,如果我导航到对象资源管理器中的一个表,转到它的索引,转到它的属性,然后查看碎片选项卡,顶部有 2 行对我来说,页面充满度百分比和总碎片百分比。
我也有一个偶尔用于索引信息的查询。修剪掉一些不相关的字段,这是查询:
SELECT t.name, ix.name, avg_fragmentation_in_percent
FROM sys.indexes AS ix
INNER JOIN sys.tables t ON t.object_id = ix.object_id
INNER JOIN sys.schemas s ON t.schema_id = s.schema_id
INNER JOIN sys.dm_db_index_physical_stats (db_id(), NULL, NULL, NULL, 'DETAILED') ps ON t.object_id = ps.object_id AND ix.index_id = ps.index_id
WHERE ix.index_id > 0
AND ix.name IS NOT NULL
当我运行这个查询时,我得到 3 列,前 2 列指向索引本身,对于这个查询,第三列是该索引的碎片百分比。
这 2 个数字通常非常接近,有时相同,但也可能经常不同。我遇到过差异很大的情况,在某些情况下超过 50%,但通常情况下它是 <1% 对 15-30%。查询结果几乎总是较高的百分比。
重建索引将使这两个数字完全或几乎为零(尽管不一定都为零)。所以我现在有 2 个数字用于索引上的碎片。根据sys.dm_db_index_physical_stats和Index Properties(FragmentationPage)的文档,两者都应该是索引的逻辑碎片,因此它们应该始终是相同的数字。对于应该相同的统计数据,我怎么会得到不同的数字?
我正在为 SQL Server 2012 EE 制定一项计划,以正确缩小和键入(nchar 到 char 类型)一些不必要的 Unicode nvarchar(max) 字段,并希望通过一次性收缩来优化数据库大小作为停机时间的一部分。实验显示节省了 50% 的分配空间,即 11G 数据。
经过阅读和试验,很明显缩小数据库会导致索引碎片,重建索引会导致数据库扩展。真实的 Catch-22 情况。我不想在数据库中留下 50% 的可用空间,在这种情况下是 11G 的磁盘存储空间。
以下是一次性缩减的一种不错的方法,它允许以非碎片索引和最新的索引统计信息结束吗?
o 带验证的备份和重复备份。
o 删除所有索引。
o 通过复制到新表重建任何太胖的表,然后删除并重命名表。这目前运作良好。
o 缩小数据库,留出合理数量的可用空间。
o 重新创建所有被删除的索引。
o 验证数据库并检查碎片。
指出任何需要考虑的注意事项、建议、陷阱或备选方案,非常感谢。
谢谢,戴夫