我在数据库的表上创建了以下索引:
CREATE INDEX [idx_index1]
on [table1]
(col1, col2, col3)
Run Code Online (Sandbox Code Playgroud)
服务器建议以下“缺失”索引:
CREATE INDEX [idx_index2]
on [table1]
(col1, col2)
INCLUDE (col3, col4, col5, col6....)
Run Code Online (Sandbox Code Playgroud)
在我看来,修改现有索引定义以包含建议的列而不是创建需要维护的新索引似乎是合乎逻辑的。在 col1 和 col2 上进行选择的查询可以像使用 index2 一样有效地使用 index1。我是正确的还是我可能遗漏了什么?
我将大量数据导入到一个空数据库中,在开始之前我禁用了所有非唯一非聚集索引,以查看是否可以提高导入的性能。
现在我想重新启用索引,我想知道我是否可以做些什么来优化它。
有 > 100 个表和近 2,000 个索引需要重建。数据库大小为 200GB。
我正在运行的脚本的关键部分是这样的:
declare c_toggle_index cursor FORWARD_ONLY READ_ONLY for
select 'alter index ' + QUOTENAME(i.name) + ' on ' + o.name + ' rebuild'
from sys.indexes as i
Inner Join sys.objects o
On o.object_id = i.object_id
Where o.is_ms_shipped = 0
And i.index_id >= 1
and i.type > 1
and i.is_disabled = 1
Run Code Online (Sandbox Code Playgroud)
我考虑过为alter index 语句设置ONLINE=OFF,但是由于索引开始被禁用,我不确定这个设置会产生任何影响。我还考虑设置 SORT_IN_TEMPDB = ON,但由于 tempdb 文件与数据库的 .mdf 文件位于同一驱动器上,我认为这样做也没有任何好处。
在运行重建脚本时,我注意到我有很多 CXPACKET 等待类型。我真的不明白为什么会这样,或者这是一个我应该解决的问题。
最后一点可能相关:除了将数据导入数据库之外,我的整个服务器目前都处于非活动状态。没有其他用户活动需要考虑或担心;我唯一关心的是在尽可能短的时间内将数据导入数据库。
我在我们的 SQL Server 上启用了即时文件初始化,因此数据库文件的“空”部分在分配之前不会归零。我的理解是,这意味着该文件可能包含“已删除”的数据。
所以现在我想在公司外部发送一个数据库的副本(可能是一个备份文件)。但是,文件中存在所有潜在的敏感“已删除”数据。现在我想将文件中未使用的部分归零。
那可能吗?我想我可以创建一个新数据库并复制所有内容,或者可能将数据库的副本还原到另一台服务器而不启用即时文件初始化,然后使用 ShrinkFile 命令积极删除数据库文件的大部分或全部未使用部分,但是有没有更省力省时的方法呢?理想情况下是一个命令,告诉 SQL 将文件归零,就像没有启用即时文件初始化一样。
如果我在表的聚集索引上设置压缩(页或行),这与在表上设置压缩相同吗?
SQL Server 为两者提供了选项,这表明它们是不同的,但我的印象是聚簇索引和表本质上是同一件事,我对聚簇索引如何工作的心理模型告诉我压缩聚簇索引还必须压缩表。
我正在尝试将所有内容从 SQL Server 2008 R2(企业)实例移动到不同服务器上的新实例。为此,我认为(经过一些研究)我可以移动系统数据库 - master、msdb 和 model。
为了实现这一点,我已经备份了所有系统和用户数据库,我正在尝试将它们恢复到新实例。注意新实例是同一个版本的SQL,只是IP地址、实例名和端口都不一样。
我已经成功恢复了主数据库。但是当我尝试恢复 msdb 数据库时,它似乎不起作用。
我使用的命令是:
restore database msdb from disk='\\webapp\SQLBackups$\msdb.bak' with replace,recovery
Run Code Online (Sandbox Code Playgroud)
我收到的回复是:
处理了数据库“msdb”的 2912 页,文件 1 上的文件“MSDBData”。处理了数据库“msdb”的 1 页,文件 1 上的文件“MSDBLog”。消息 3283,级别 16,状态 1,服务器 SQLServerName\Instance_Name,第 1 行文件“MSDBLog”未能正确初始化。检查错误日志以获取更多详细信息。消息 3013,级别 16,状态 1,服务器 SQLServerName\Instance_Name,第 1 行 RESTORE DATABASE 异常终止。
如果我尝试执行:
restore database msdb with recovery
Run Code Online (Sandbox Code Playgroud)
我收到:
由于未恢复日志,无法恢复数据库。
我没有日志备份,因为 msdb 数据库处于“简单”恢复模式。所以我回到原来的服务器,将恢复模式切换到“完整”,创建一个新的完整备份和日志备份,然后尝试恢复这个新备份,但仍然得到相同的结果。如果我尝试访问 SSMS 中的任何内容,我只会收到一条消息,指出无法打开 msdb 数据库,因为它正处于还原过程中。
所以我似乎被卡住了。我无法使用服务器,因为它认为它正在恢复中。我不能删除 msdb 数据库,因为它是一个系统数据库。我无法完成恢复,因为无论我尝试什么选项,无论使用什么备份文件,我仍然收到消息“文件“MSDBLog”未能正确初始化”。
有任何想法吗?
我刚刚为一个相当大的数据库(1.3 TB)编写了一个备份语句,我一直在使用一个更小的数据库(10 GB + 10 GB 日志文件)对其进行测试。备份写入三个目的地。在测试期间,我注意到当备份运行时,每个备份文件的大小约为 1.2 GB,但是一旦备份过程完成,文件就会缩小到 600 MB 以下。
我有兴趣了解:
这是我正在使用的备份语句:
BACKUP DATABASE @DatabaseName
TO DISK = @backupMedia1,
DISK = @backupMedia2,
DISK = @backupMedia3
WITH COMPRESSION, RETAINDAYS = 0, NOFORMAT, INIT, NOSKIP, NAME = @DatabaseName
Run Code Online (Sandbox Code Playgroud) 我有一个非常繁忙的数据库,我被要求寻找回滚的事务。
我使用 SQL Server Profiler 来监视TM: RollbackTran Completed 事件,这表明每分钟都会发生几十个这样的事件,但它没有给我任何关于正在回滚的事务、回滚影响的对象的任何指示,或者回滚发生的原因。简而言之,它的用途似乎非常有限。
例如,如果我还尝试进行监控,以便为SQL:StmtStarting回滚提供一些上下文,那么在这个繁忙的环境中只会有太多噪音,无法识别哪个语句负责回滚。
我也试过运行语句
SELECT *
FROM fn_dblog (NULL, NULL)
WHERE Operation = 'LOP_ABORT_XACT';
Run Code Online (Sandbox Code Playgroud)
但这并没有返回任何结果(考虑到 SQL Profiler 报告的回滚次数,这似乎很奇怪)。
有什么方法可以生成显示已回滚事务的报告?
蒂亚!
我有一个双节点 SQL 集群 (2008 R2)。
该 SQL 实例中的一些数据库被镜像到远程站点上的另一台服务器,使用具有自动故障转移的高安全性。这些数据库的镜像连接超时值设置为 90 秒。
当我将 SQL 从集群中的一个节点移动到另一个节点时,使用故障转移集群管理器应用程序的“将此服务或应用程序移动到另一个节点”选项,被镜像的数据库会立即故障转移到镜像。
这是不受欢迎的行为。我设置镜像连接超时值的原因是我只想在集群完全失败并且没有运行节点的情况下故障转移到数据库镜像。
有没有办法实现这一目标?感觉好像应该是可能的,否则混合集群和自动故障转移数据库镜像的概念将是行不通的,因为集群内的每个节点故障转移都会触发镜像故障转移。
谢谢。
Microsoft 建议不要费心重建少于 1,000 页的索引(从内存中我认为这是因为它们太小以至于它们将被保存在 RAM 中)。
如果我不重建它们,那么它们将变得非常支离破碎。在那种情况下,拥有它们有什么意义吗?我正在想象一个电话簿,其中每个条目都位于错误的位置 - 这将毫无用处!
为了澄清起见,我主要谈论的是非聚集索引,但我很想知道聚集索引的答案是否会有所不同。
这个问题的答案表明索引可以帮助避免行锁背后的阻塞问题,这就是为什么索引在正确并适用于 SQL Server 的情况下仍然有用的原因。
我在实时服务器 (SQL Server 2008 R2) 上创建了一个非聚集索引,但结果却没有提供我所希望的性能优势。所以我想再次删除索引。
不幸的是,我无法锁定正在使用的索引。它可能总是会被使用。重新启动 SQL Server 并不是一个真正的选择。
过去我想重建索引时也遇到过同样的问题,我不得不通过重新组织来解决这个问题(有时效率很低)。
有没有办法告诉 SQL Server 停止使用索引?或者是否可以运行一个查询来尝试获取索引的排他锁,无限期等待,然后删除索引?还有其他选择吗?或者我是否只需要等到出现某种中断,然后希望我记得在一切恢复联机之前将其删除?
我目前正在做一些监控 SQL Server 性能的工作。我发现以下脚本 [1] 计算“页面查找百分比” - 建议是“好”值小于 100。
SELECT 1.0*cntr_value /
(SELECT 1.0*cntr_value
FROM sys.dm_os_performance_counters
WHERE counter_name = 'Batch Requests/sec')
AS [PageLookupPct]
FROM sys.dm_os_performance_counters
WHERE counter_name = 'Page lookups/sec'
Run Code Online (Sandbox Code Playgroud)
现在我已经在大约十几个不同的服务器上运行了这个脚本——大部分是虚拟的,但有几个物理的,主要是 2008R2 Enterprise,但有几个 2005,一些是实时的,一些是开发的,甚至是一个物理的 2008R2 Express 版本,它只是一个见证服务器并且当前处于休眠状态(没有设置镜像以进行主动故障转移)。只有其中一台服务器的值低于 100。在大多数情况下,它一直在 1000 左右,或者至少在 100 左右。在休眠的见证服务器上,价值是荒谬的 20,000 !
这是否表明我们在这方面存在广泛的问题,或者对于为什么在这么多不同的服务器上这个数字应该如此之高,是否有一些无辜的解释?我们在其中一些服务器上遇到了性能缓慢的问题,因此更好地了解这个数字告诉我的内容对我很有用。
[1] - http://thomaslarock.com/2012/05/are-you-using-the-right-sql-server-performance-metrics/
sql-server ×7
index ×4
backup ×1
clustering ×1
compression ×1
import ×1
index-tuning ×1
locking ×1
mirroring ×1
performance ×1
profiler ×1
rollback ×1
ssas ×1
ssdt ×1