我正在研究对数据库进行碎片整理,似乎我正在寻找以下 SQL 语句:
ALTER INDEX ALL ON mytablename
REBUILD WITH(ONLINE = ON)
Run Code Online (Sandbox Code Playgroud)
当我从 中提取信息时sys.dm_db_index_physical_stats,我看到百分比非常高 - 70%、80% 和 90% (!)。所以这告诉我我想要一个REBUILD,而不是一个REORGANIZE。
在执行这些之前,我有几个问题REBUILDS。
ONLINE = ON
告诉我是的,但我想确认它不会崩溃。)还是在不使用时运行更好?REBUILD使事情运行得更慢。那是在重建索引的时候吗?(或永远之后)编辑:最后,重建它的最佳方法是什么?循环遍历百分比大于 30 的所有对象?或者?
谢谢!
我们的生产 SQL Server 2005 数据库的数据文件位于一个单独的物理驱动器上,Microsoft Windows 2003 的磁盘碎片整理程序工具报告为 99% 是碎片化的。
我们安排了一个任务,在星期六早上 3:00 对这个驱动器进行碎片整理。作业在 40 分钟后完成,没有明显错误。但是,驱动器仍然严重碎片化。
我们应该在整理碎片之前停止 SQL Server 服务吗?
语境
每个上下文请求:我们有一个 Microsoft SQL Server 2005 实例 (9.00.5324.00) 在 Dell PowerEdge 2950 硬件上运行 32 位 Windows Server 2003 (SP2),大约 2007 年,具有 4GB RAM。PowerEdge 2950 有四个 68GB 驱动器配置为 RAID-1 以创建两个 68GB 虚拟磁盘:(1) C(引导和操作系统)&D(页面文件,其他杂项数据);(2) E(SQL 数据)。据我所知,IT 人员从未对这些驱动器进行过碎片整理……磁盘碎片整理程序报告的文件碎片率为 66% (C)、77% (D) 和99% (E)。性能监视器报告以下平均结果:“分页文件:使用率百分比”= ~6.8%;“SQL Server:缓冲区管理器 - 页面预期寿命”= 20 秒;和“PhysicalDisk:平均磁盘秒/写入,驱动器 E”= 之间 300 和 1,. 我们将在几个月内进行急需的硬件和 SQL Server 升级(即,新硬件、64 位 Windows …
我的数据库文件增长非常快(设计者不是我,只是每周报告使 7 GB 增长)。最后,我的磁盘空间不足。以及计数的未报告周数。
我有一些选择可以执行,但需要您的建议:
缩小数据库(缩小是否为操作系统提供了空间?)
从外部磁盘或网络存储分离和附加 DB。(SQL Server 2005 是否支持网络存储?)
将 RAID 配置从 1 更改为 5 以将磁盘大小增加一倍。(这是最安全的选择,但也有 RAID 配置更改的危险。)
感谢这些关于我的问题的伟大而有用的答案。我检查了日志文件,99% 的空间未使用。所以,我缩小了它。由于 DB 仅在我们需要一些报告时使用(按时间请求,并不总是需要访问 db )我认为性能对我来说不是问题。
我有一个数据库,我们目前全天运行事务日志备份,准确地说是每 30 分钟一次,我们每天凌晨 2 点运行一次完整备份。
每个星期六凌晨 3 点,我们都有一个作业设置来重建所有表上的索引。
话虽如此,进行索引重建会导致我们的事务日志大幅增长。我正在考虑不同的想法来减少所需的额外驱动器空间(重新索引后大约 25GB)。
我正在考虑在重建任务之前将数据库恢复模型设置为简单,以防止记录所有索引重建,然后在重建完成后将其设置回完整。
还有其他人使用这种方法吗?或者任何人都可以提供有关为什么这可能是一个坏主意的见解/建议?或者关于如何在执行数据库维护任务时处理巨大日志文件的任何提示?
如果用户从不运行REBUILD或REORGANIZE在他们的数据库上运行,SQL Server 是否仍然以某种方式对索引进行碎片整理?
MSDN 建议,如果索引超过 30% 的碎片,建议运行REBUILD而不是REORGANIZE. REORGANIZE多次运行会做同样的事情REBUILD吗?
我对此感到疑惑,因为我有一个具有高度碎片化索引的客户端。他们REORGANIZE每个周末都运行该索引,随着时间的推移,他们的索引似乎被整理了碎片。
这有意义吗?
我们正在删除旧的存储过程和表。
我怎么知道最近没有调用哪些程序?
dm_exec_procedure_stats并且dm_exec_query_stats不可靠,因为它们只返回计划缓存中的过程。
我们确实为 SQL Server 2008 r2 express 制定了一些维护计划。如果任何表的页数超过 50 并且平均碎片超过 20,我们每个月都会对数据库进行碎片整理。
如果数据库日志大小>2MB,则恢复模式为简单,收缩,恢复模式重新设置为FULL。如果 Page_count>50 且 avg_fragmentation_in_percent > 30,则索引为 REBUILD。
如果 Page_count>50 且 avg_fragmentation_in_percent > 5 且 <30,则索引为 REORGANIZE。
这就是我们目前正在做的事情。但是我们发现自增长事件是资源密集型的,不应重复发生。现在,对于所有数据库,mdf 文件的自动增长设置为 MB,ldf 文件设置为 10%,这是创建新数据库时的默认值。我们计划根据每天变大的数据库数量来增加数据库的自动增长值。但是我想知道有多少自动增长事件对数据库来说是理想的。我应该设置自动增长以便它每天、每周或每月等只发生一次吗?所以请帮助我为我的数据库设置自动增长值。还有另一个问题,如果我每月对数据库进行碎片整理,那么它就会缩小。因此,在此之后,对于所有我确实收缩过的数据库,在写入新数据时都会发生一次自动增长。所以会有很多自动增长事件。那么会不会有问题呢?请告诉我一个解决方案。
我在所有服务器上运行 Ola Hallengren 脚本以进行索引和统计维护。当我查看命令日志表时,我注意到命令结束和下一个命令开始之间的时间很长。有时这个间隔会超过一个小时。
有没有其他人在他们的系统上观察到这一点?我可以做些什么来缩短(我猜)要维护的项目之间的发现时间?下面是我运行它们的参数集。
sqlcmd -E -S $(ESCAPE_SQUOTE(SRVR)) -d master -Q "EXECUTE [dbo].[IndexOptimize]
@Databases = 'USER_DATABASES',
@LogToTable = 'Y',
@FragmentationLow = NULL,
@FragmentationMedium = 'INDEX_REORGANIZE,INDEX_REBUILD_ONLINE,INDEX_REBUILD_OFFLINE',
@FragmentationHigh = 'INDEX_REBUILD_ONLINE,INDEX_REBUILD_OFFLINE',
@FragmentationLevel1 = 50,
@FragmentationLevel2 = 80,
@UpdateStatistics = 'ALL',
@OnlyModifiedStatistics = 'Y' " -b
Run Code Online (Sandbox Code Playgroud)
所以当我运行这个时:
SELECT DATEDIFF(MINUTE, cl.StartTime, cl.EndTime)
, *
FROM master.dbo.CommandLog AS cl
WHERE cl.StartTime > '2014-12-13'
ORDER BY cl.ID
Run Code Online (Sandbox Code Playgroud)
我看到这个:

在某些情况下,我被告知不要对生产中的表执行 VACUUM FULL(或 CLUSTER),因为这将独占锁定它的时间比预期的要长。这同样适用于几个 ALTER TABLE 操作(例如更改几个列的类型)。
提出的替代方案始终是执行以下操作:
CREATE TABLE new_table AS SELECT * FROM old_table ;
-- recreate all indices and constraints
ALTER TABLE old_table RENAME TO going_to_drop_table ;
ALTER TABLE new_table RENAME TO old_table ;
DROP TABLE going_to_drop_table ;
Run Code Online (Sandbox Code Playgroud)
这适用于没有依赖关系的场景old_table(意味着没有任何依赖它的视图,也没有任何外键约束、函数等),并且old_table没有任何插入或更新。但在大多数数据库中,这将是一个例外,而不是规则。
有没有办法在不丢失依赖关系的情况下进行这样的“表交换”?
[为了完整起见:我对如何为 PostgreSQL 9.5 或 9.6 做这件事特别感兴趣]
pg_repack。注意事项:在 Windows 上可能不容易实现,未使用 postgresql 9.6 进行测试。看起来是最有希望的选择。pg_reorg: 类似于 pg_repack(是它的基础)=> 自 postgresql 9.4 以来似乎没有更新,并且它主要被pg_repack.postgresql optimization maintenance online-operations postgresql-9.6
当我将 Ola Hallengren 的备份脚本部署到我的服务器时,我总是将@CleanupTime日志备份的参数设置为零。这样,每次运行日志备份作业时,它都会检查早于上次完整备份的日志备份文件并将其删除。但是,对于完整COPY_ONLY备份也是如此!COPY_ONLY为了删除旧的日志备份文件,日志备份作业应该只检查最后一次非完整备份。
只是想知道我是否是唯一遇到这种情况的人,或者我的建议是否合理。如果我需要在中间进行完整副本备份以 IDK 刷新 TEST 数据库,则该仅副本备份不应影响常规的每日备份顺序。请让我知道你的想法。
sql-server backup maintenance sql-server-2012 ola-hallengren
maintenance ×10
sql-server ×8
index ×2
backup ×1
optimization ×1
postgresql ×1
shrink ×1
storage ×1