标签: sql-server

为什么 SQL Server 在更新位列时扫描所有行,即使是通过链接服务器进行主键

我对 SQL 链接服务器的特定主键使用简单的更新语句,如下所示

UPDATE t
SET
    processed = 1,
    processed_on = GETDATE()
FROM [LINKED\SERVER].DATABASE.dbo.FileQueue t
WHERE t.FileId = '3b33eff6-fde1-4e8c-9c23-2dbd45f50222'
Run Code Online (Sandbox Code Playgroud)

两台服务器都是SQL Server 2019。表定义是

CREATE TABLE dbo.FileQueue
(
    FileId UNIQUEIDENTIFIER NOT NULL,
    Processed BIT NOT NULL,
    Processed_on DATETIME NULL
 CONSTRAINT PK_FileQueue PRIMARY KEY CLUSTERED 
 (
    FileId ASC
 )
)
Run Code Online (Sandbox Code Playgroud)

已处理列具有位类型。由于全表扫描,查询速度很慢。

查询计划

为什么会发生这种情况?当我从语句中删除位列时,读取和更新单个远程行一切正常。

Id列是聚集主键。我有很多带有相似键的表。

我尝试使用CONVERTorCAST函数,结果是相同的。

对于没有位列的查询,执行计划非常好。

UPDATE t
SET
    --processed = 1,
    -- any other columns can be added to be updated except bit
    processed_on = GETDATE()
FROM …
Run Code Online (Sandbox Code Playgroud)

sql-server execution-plan linked-server update

9
推荐指数
1
解决办法
884
查看次数

MS SQL Server 数据库事务日志增长率

我有一个繁忙的数据库,它已经繁忙多年,并且我看到事务日志大小每天约为几 GB。

在过去几周内,事务日志大小已增加到每 6 小时 40-50 GB。这对我的备份产生了很大的影响,并且磁盘的大小也令人担忧。

我每隔一天进行一次完整备份,每 6 小时进行一次日志备份。

日志备份按预期减少了事务日志使用量的大小,但它又开始迅速增加。

如何发现导致交易量相对突然增加的原因?

  • 我的开发人员正在对可能影响过去几周的变化进行空白
  • 没有长时间运行的进程
  • 没有计划的作业来执行索引操作
  • Redgate 监控未显示任何过度写入

我该如何进一步调查?

sql-server backup transaction-log sql-server-2017

9
推荐指数
1
解决办法
1020
查看次数

当表上有两个唯一索引且一个索引中的所有列也在另一个索引中时,是否会造成性能损失?

在我的数据库中,我有一个带有两个索引的表。出于数据完整性原因,a、b 列上有一个唯一索引 #1。我有另一个索引 #2,其中包含 c、a、b 列,用于性能原因。我注意到这个索引#2 也是唯一的。

在我看来,索引#2 的唯一性似乎是多余的,因为索引#2 中不可能有重复值,而索引#1 中也不可能有重复值。我很想更改索引 #2,使其不再唯一,因为我想象数据库引擎可能会对索引 #2 中的 c、a、b 执行第二次检查,以确保每次插入行时这些列的唯一性,从而导致即使永远不会有重复的值,也会影响性能。它是否正确?

有没有办法删除 a、b 上的索引 #1 并保留 c、a、b 上的索引 #2,但仍然只对 a、b 列施加唯一约束,而不维护两个单独的索引?这将允许我只有一个索引包含所有三列,但仍然对 a、b 强制执行数据完整性约束。为了提高性能,我不需要在 a、b 上建立索引,因为我所有的选择查询都在 where 子句中包含 c 列。这是否是唯一约束而不是索引的用例?我认为数据库引擎基本上以相同的方式对待这两个构造(请参阅这篇文章:何时应该使用唯一约束而不是唯一索引?)。

请记住,索引不是冗余的,但索引的“唯一性”是冗余的。看起来让索引 #2 变得不唯一是理所当然的。但这会带来任何实际的性能提升吗?即使索引 #1 中的列完全包含在索引 #2 中,数据库是否检查两个索引的唯一性?

一些答案询问了用于从此表中选择数据的示例查询。以下是最常见的:

Select [some other columns] from table where c=1 and a=2
Select [some other columns] from table where c=1
Select [some other columns] from table where c=1 and a=2 and b=3
Run Code Online (Sandbox Code Playgroud)

这些查询通常包括选择不在任何索引中的许多其他列。

我们通常不会运行这样的查询:

Select [stuff] from table …
Run Code Online (Sandbox Code Playgroud)

sql-server index-tuning unique-constraint

9
推荐指数
1
解决办法
1608
查看次数

SQL Server 如何更新索引视图?

每次在索引视图引用的基表中插入、更新或删除数据时,数据库引擎都会自动更新索引视图以反映更改。但是,我不太确定数据库引擎如何更新索引视图。它是否完全重新运行视图中的查询,或者是否使用更有效的方法仅更新相应的部分?

sql-server materialized-view

9
推荐指数
1
解决办法
2180
查看次数

创建索引然后删除它是否会使数据库返回到索引创建前的状态?

我正在测试一些索引,并希望对哪些索引表现更好(主要是索引中字段的顺序和指定的其他字段)进行一些 AB 测试。

我有正在测试的数据库的备份,但该备份需要很长时间才能恢复。我更希望能够创建索引 foo,收集性能指标,然后删除 foo 以将数据库返回到索引前状态并创建索引 bar。这是索引创建的工作方式,还是索引的创建会以某种方式改变表,而删除索引无法撤消?

index sql-server index-tuning

9
推荐指数
3
解决办法
1749
查看次数

运行 sys.fn_dump_dblog 时,WITH EXECUTE AS SELF 返回错误

我正在尝试将存储过程配置为 EXECUTE AS 具有 sysadmin 权限的用户,以允许非特权用户从未记录的 TVF 获取结果sys.fn_dump_dblog

我正在作为角色成员创建该过程sysadmin,但是当我随后尝试使用该子句运行该过程时WITH EXECUTE AS SELF,出现以下错误:

消息 9011,级别 14,状态 1,过程 dbo.read_log,第 16 行 [批处理开始第 65 行] 用户无权使用虚拟表 DBLog 查询备份文件。只有 sysadmin 固定服务器角色的成员才有此权限

这对我来说似乎很奇怪,因为我是服务器角色的成员sysadmin,并且WITH EXECUTE AS SELF在过程定义中指定子句应该会导致使用我的用户帐户执行该过程。根据学习网站

EXECUTE AS SELF 相当于 EXECUTE AS user_name,其中指定的用户是创建或更改模块的人。创建或修改模块的人员的实际用户 ID 存储在 sys.sql_modules 或 sys.service_queues 目录视图的execute_as_principal_id 列中。

如果我WITH EXECUTE AS SELF从过程的定义中删除该子句,TVF 将按预期返回结果。

以下是SQL Server 2019 中的最小、完整且可验证的示例。

首先,证明我们是该sysadmin角色的成员:

USE [master];
GO
SELECT 
      [roles].[name]
FROM sys.server_principals [members] …
Run Code Online (Sandbox Code Playgroud)

sql-server permissions sql-server-2019

9
推荐指数
1
解决办法
468
查看次数

这是 Oracle Where exists (Select NULL FROM...) 中的一种新的常见模式吗?

多年前,写

where exists (Select * from some_table where some_condition)
Run Code Online (Sandbox Code Playgroud)

去年我注意到许多 t-sql 脚本切换到使用数字 1 而不是星号

where exists (Select 1 from some_table where some_condition)
Run Code Online (Sandbox Code Playgroud)

就在所以我看到了这个 Oracle 示例

WHERE EXISTS (SELECT NULL FROM ...
Run Code Online (Sandbox Code Playgroud)

这是 Oracle 的常见模式吗?哪些是使用这样的东西的性能参数。

oracle sql-server style

8
推荐指数
2
解决办法
1117
查看次数

完整计划缓存行为

在 SQL Server 2005 中,当计划缓存填满时会发生什么?我做了一些研究,从收集的点点滴滴来看,似乎缓存计划被赋予了一个“年龄”,其中包括它的重量或编译成本,乘以自缓存以来运行的次数。随着时间的推移,这个年龄递减,直到它达到 0,当它被认为“老化”并且是需要时冲洗的候选者。当计划缓存填满时,过时的计划将从缓存中刷新。

幕后是否还有其他事情使这种情况复杂化?

谢谢,

马特

sql-server-2005 sql-server

8
推荐指数
1
解决办法
609
查看次数

SQL Server IsShutdown 属性对于确定数据库是否处于良好状态有用吗?

我公司有一个工具可以监控服务器、服务、数据库等的状态。我们为我们的客户监控一些现场服务器。执行的一项特别简单的检查是通过查询某些数据库属性的值来确定 SQL Server 数据库是否处于“良好”状态。我们监控的四个数据库属性是:

  • 怀疑
  • 离线
  • 是紧急模式
  • 是关闭

这是我们使用的查询:

SELECT name AS [SuspectDB],
  DATABASEPROPERTY(name, N'IsSuspect') AS [Suspect],
  DATABASEPROPERTY(name, N'IsOffline') AS [Offline],
  ISNULL(DATABASEPROPERTY(name, N'IsShutdown'), 1) AS [Shutdown],
  DATABASEPROPERTY(name, N'IsEmergencyMode') AS [Emergency]
FROM sysdatabases
WHERE (DATABASEPROPERTY(name, N'IsSuspect') = 1)
   OR (DATABASEPROPERTY(name, N'IsOffline') = 1)
   OR (ISNULL(DATABASEPROPERTY(name, N'IsShutdown'), 1) = 1)
   OR (DATABASEPROPERTY(name, N'IsEmergencyMode') = 1)
Run Code Online (Sandbox Code Playgroud)

在测试升级到 SQL Server 2008 时,我们的许多数据库似乎都为IsShutdown属性返回了 1(真)值。SQL Server 2005 以前从未出现过这种情况。该属性的MSDN 文档只是说明“数据库在启动时遇到问题”。

据我所知,数据库非常好。它们已启动,可以查询等。没问题。

是否IsShutdown财产真正的问题对我的监视目的,即,它表明该数据库是在一个糟糕的状态?或者我应该从我的查询中删除它?

注意:在与我们的一位常驻 DBA 交谈时,他们发现在我们的一些新 SQL Server 2008 数据库上,启用IsAutoClose属性的事实可能与这些数据库的 …

sql-server

8
推荐指数
1
解决办法
420
查看次数

为什么在列上运行 ALTER TABLE 会导致它从 NOT NULL 变为 NULL?

我正在批量更新 SQL Server 数据库。我将所有numeric(38,0)列更改为int (是的,SQL Server 脚本是从 Oracle 脚本创建的)。使用 SMO 和 C# (我是一名软件工程师),我设法生成了非常好的脚本,就像SQL Server Management Studio那样。除了一个特定问题外,一切都非常好:

对于少数表格,当我调用ALTER TABLE [myTable] ALTER COLUMN [columnA] INT它时,它决定还将列从NOT NULL to NULL. 这当然是一个大问题,因为我需要为那些特定列上的大多数表重新生成主键。

显然,我有很多选择使用 SMO 来找出哪些列是主键,并在我更新数据类型之后或同时强制它们为 NOT NULL,但我真的很好奇是什么导致了这种情况。

sql-server-2005 sql-server-2008 sql-server

8
推荐指数
1
解决办法
460
查看次数