我们在 SQL 2005 上有一个生产数据库服务器。一切正常运行了一段时间,但几周后我们看到性能显着下降。只有重新启动 SQL Server 才能使性能恢复正常。
一些背景:
我们在非高峰时间尝试了几件事: - 运行 DBCC DROPCLEANBUFFERS(带有 CHECKPOINT)以清除数据缓存。它没有任何效果,也不会清除任何 RAM 使用量)。- 运行 FREEPROCCACHE 和 FREESYSTEMCACHE 以清除查询计划和存储的 proc 缓存。没有效果。
显然,在活跃的生产环境中重新启动 SQL Server 并不理想。我们缺少一些东西。还有其他人经历过这个吗?
更新:2012 年 4 月 28 日 仍在与这个问题作斗争。我已将 SQL Server 的内存降低到 10 GB,只是为了排除与操作系统的任何争用。我越来越接近缩小范围,但下一步需要一些帮助。
这是我发现的,重新启动 SQL Server 后,页面文件在 12.3 GB 和 12.5 GB 之间徘徊。它会保持这种状态好几天。服务器线程总数将在 850 到 930 之间挂起 - 在几天内也保持稳定和一致(sqlserver 稳定在 55 到 85 之间,具体取决于流量)。
然后,有一个“事件”。我不知道事件是什么,我在日志中看不到它,也看不到在星期几或它发生的时间有任何一致的东西,但是他的页面文件突然跳到了 14.1 或 14.2 …
我们有一个非常大的数据库(~6TB),其事务日志文件被删除(SQL Server 关闭时。我们尝试过:
...但到目前为止没有任何效果。
我们目前正在运行:
ALTER DATABASE <dbname> REBUILD
LOG ON (NAME=<dbname>,FILENAME='<logfilepath>')
Run Code Online (Sandbox Code Playgroud)
...但考虑到数据库的大小,这可能需要几天时间才能完成。
上面的命令和下面的命令有区别吗?
DBCC CHECKDB ('<dbname>', REPAIR_ALLOW_DATA_LOSS)
Run Code Online (Sandbox Code Playgroud)
我们应该执行REPAIR_ALLOW_DATA_LOSS吗?
值得注意的是,数据来自其他来源,因此可以重建数据库,但是我们怀疑修复数据库比再次重新插入所有数据要快得多。
更新
对于那些记分者:ALTER DATABASE/REBUILD LOG命令在大约 36 小时后完成并报告:
警告:数据库“dbname”的日志已重建。事务一致性已丢失。RESTORE 链被破坏,服务器不再拥有先前日志文件的上下文,因此您需要知道它们是什么。
您应该运行 DBCC CHECKDB 来验证物理一致性。数据库已置于 dbo-only 模式。当您准备好使数据库可供使用时,您将需要重置数据库选项并删除任何额外的日志文件。
然后我们运行了一个DBCC CHECKDB(大约需要 13 小时),它成功了。假设我们都了解了数据库备份的重要性(以及授予项目经理访问服务器的权限......)。
这是一个后续问题:https : //stackoverflow.com/questions/7684477/is-it-possible-to-set-transaction-isolation-level-snapshot-automatically
尽管READ_COMMITTED_SNAPSHOT ON.
所以我有两个问题:
注意SQL Server 在验证外键时获取共享锁,即使事务使用的是已提交读快照(使用行版本控制已提交读)或快照隔离级别。在使用这些事务隔离级别时检查事务的死锁图时请注意这一点。如果您看到共享锁,请检查是否在外键引用的对象上获取了这些锁。
我如何检查 FK 是否真的对死锁/超时情况负责,这是否意味着我可以删除这些外键以防止死锁(什么是可以接受的努力)?
注意:我只是从导致死锁的表中读取数据。
非常感谢有关此主题的任何想法。
编辑 这里是一个死锁图。也许有人可以帮助我了解导致僵局的原因。当两个事务想要写入同一个表(一个更新和一个插入,插入作为存储过程)时,似乎没有任何报告运行仅由 Web 应用程序引起。为什么它需要页锁以及如何只启用行锁?Insert-SP 已经使用TRANSACTION ISOLATION LEVEL REPEATABLE READ.
我强烈怀疑两个触发器(一个更新和一个插入)是造成死锁的原因。这是插入触发器:
CREATE TRIGGER [dbo].[CreateRMAFiDates]
ON [dbo].[RMA]
AFTER INSERT
AS
BEGIN
SET NOCOUNT ON;
UPDATE RMA
SET [fiCreationDate]=(SELECT idDate FROM tdefDate
WHERE CONVERT(VARCHAR, INSERTED.Creation_Date, 112) = tdefDate.Text),
[fiPopDate]=(SELECT idDate FROM tdefDate
WHERE CONVERT(VARCHAR, INSERTED.POP_Date, 112) = tdefDate.Text),
[fiManufactureDate]=(SELECT idDate FROM tdefDate
WHERE …Run Code Online (Sandbox Code Playgroud) 有人向我建议,在 t-SQL 批处理中使用 IF 语句对性能有害。我试图找到一些确认或验证这个断言。我使用的是 SQL Server 2005 和 2008。
断言是以下批次:-
IF @parameter = 0
BEGIN
SELECT ... something
END
ELSE
BEGIN
SELECT ... something else
END
Run Code Online (Sandbox Code Playgroud)
SQL Server 无法重用生成的执行计划,因为下一次执行可能需要不同的分支。这意味着 SQL Server 将从执行计划中完全删除一个分支,因为它已经可以确定当前执行需要哪个分支。这是真的吗?
此外,在这种情况下会发生什么:-
IF EXISTS (SELECT ....)
BEGIN
SELECT ... something
END
ELSE
BEGIN
SELECT ... something else
END
Run Code Online (Sandbox Code Playgroud)
无法提前确定将执行哪个分支?
performance sql-server-2005 sql-server-2008 sql-server query-performance
在 SQL Server 2005 上,我们每周进行一次完整备份,每晚进行一次增量备份。
我想知道是否可以从备份中恢复单个表,无论是源数据库还是不同的数据库。
我在网上找不到任何明确的答案。
提前致谢。
我今天在我们的数据库中遇到了一个视图,其中 where 子句中的第一个语句是where 1 = 1. 这不应该对每条记录都返回 true 吗?如果不过滤任何记录,为什么有人会写这个?
是否可以运行 SQL 命令来确定数据库的恢复模式?我想知道它是否完全恢复。
我有一个 SQL Server 2008 数据库,它的数据文件大小约为 2GB,但日志文件超过 8GB。对于 2008 之前的数据库,我可以使用“备份日志”和该TRUNCATE_ONLY选项,但 2008 及更高版本的数据库不再提供此选项。
我确实有一个截断日志文件的脚本:
USE [MyDatabase]
GO
ALTER DATABASE [MyDatabase] SET RECOVERY SIMPLE WITH NO_WAIT
DBCC shrinkfile('MyDatabase_log', 1)
ALTER DATABASE [MyDatabase] SET RECOVERY FULL WITH NO_WAIT
GO
Run Code Online (Sandbox Code Playgroud)
这会完全截断日志文件,但我的问题是:这会影响性能吗?
我每天执行两次完整备份,因此就数据前滚而言,日志实际上不是必需的。
我们收到了有关查询运行缓慢或在清晨超时的报告,我看到的唯一一项我认为可能会影响它的作业是我们的数据库备份作业。
数据库本身大约有 300GB,备份工作从凌晨 4:30 开始,直到早上 7:00 之后才完成。我们备份作业的当前语法是:
BACKUP DATABASE [DatabaseName]
TO DISK = N'E:\Database Backups\DatabaseName.Bak'
WITH INIT, NOUNLOAD, NAME = N'DatabaseName.Bak',
NOSKIP, STATS = 10, NOFORMAT
Run Code Online (Sandbox Code Playgroud)
E:\ 是服务器上的一个分区,其中包含数据库和数据库备份。
还应该注意的是,这是一个虚拟服务器,而不是专用的独立服务器。在我们切换到虚拟服务器后,我们开始收到关于备份过程中速度变慢的抱怨,所以我认为这可能是相关的。
有没有办法运行此备份作业,使其在运行时不影响查询性能?
我们使用的是 SQL Server 2005
为什么这个CASE表达式:
SELECT CASE column
WHEN 'a' THEN '1'
WHEN 'b' THEN '2'
... c -> i
WHEN 'j' THEN '10'
WHEN 'k' THEN '11'
END [col]
FROM LinkedServer.database.dbo.table
Run Code Online (Sandbox Code Playgroud)
产生这个结果?
错误消息:
无法准备消息 8180,级别 16,状态 1,第 1 行语句。
消息 125,级别 15,状态 4,第 1 行
Case 表达式只能嵌套到级别 10。
显然这里没有嵌套CASE表达式,尽管有 10 多个“分支”。
另一个怪事。这个内联表值函数产生相同的错误:
ALTER FUNCTION [dbo].[fn_MyFunction]
(
@var varchar(20)
)
RETURNS TABLE
AS
RETURN
(
SELECT CASE column
WHEN 'a' THEN '1'
WHEN 'b' THEN '2'
... c -> i …Run Code Online (Sandbox Code Playgroud) sql-server-2005 sql-server-2008 sql-server sql-server-2000 linked-server
sql-server-2005 ×10
sql-server ×9
performance ×2
backup ×1
dbcc-checkdb ×1
deadlock ×1
recovery ×1