标签: sql-server

重新构建 HEAP 会导致停机吗?

这是一个有点尴尬的问题,我不敢相信我已经错过了这么多年。

我有一个包含 401 个堆表的供应商第三方数据库。我最近开始使用 Brent Ozar 的脚本并设置sp_BlitzFirst为每 15 分钟运行一次以收集等待统计信息等。

它发现的是每次运行 24 小时期间,它都告诉我修复转发记录。可能会让一些读者感到震惊的是,我在 DMV 上运行了一个查询,并取回了一些包含超过 150,000 个转发记录值的表。

我明白要解决这个问题是在整个表中有一个聚集索引,或者作为运行ALTER TABLE [tablename] REBUILD.

然而,我无法找到的是这是否会使表脱机,以及在运行此命令之前我是否应该注意其他任何问题。

我正在使用 2008 R2 的企业版,我想知道以这种方式运行它是否会消除中断的需要?

ALTER TABLE [tablename] REBUILD WITH (ONLINE = ON);  
Run Code Online (Sandbox Code Playgroud)

有人对这个有经验么?

sql-server maintenance sql-server-2008-r2 heap online-operations

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

在 SQL Server 2016 中结合始终加密和列级加密

我们有使用 SQL Server 2016 加密敏感列数据的要求,并选择了 Always Encrypted(AE) 功能来使用确定性方法加密这些列。

由于 AE 确定性加密不允许对这些加密列进行不等式、范围或 LIKE 查询,因此我们尝试使用对称密钥(列级)加密技术对这些类型的列进行加密。

在某些列(不需要任何不等式、范围或 LIKE 查询)上实现 AE 功能并在需要生成不等式、范围或 LIKE 查询的列上实现对称密钥类型加密是否是一个好习惯?

考虑到性能、安全性和维护性,将 AE 加密和列级加密结合在一个表上是一个好习惯吗?

请专家指教。

sql-server encryption sql-server-2016 always-encrypted

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

从 SQL Server 查询外部 LDAP 服务器

我对查询 LDAP 服务器进行了广泛的研究,但到目前为止还没有解决。所以请高手帮忙

背景:我有一个客户端,其 LDAP 服务器是 OnPremise(虽然面向公众),我在防火墙内有一个 SQL Server(2012 SE)。外部 LDAP 和内部 SQL Server 之间的通信很好,因为我可以互相 ping 通。我还创建了一个远程域帐户,并在 SQL Server 上创建链接服务器时使用了该帐户。我还有我们的内部域控制器,它具有域信任关系。现在,我使用域帐户创建了 2 个链接服务器,但我无法在内部和外部查询 LDAP 服务器。我希望这是有道理的。无论如何,这是我的链接服务器的定义和我收到的错误

[已解决] 链接服务器到内部 LDAP 服务器:这是通过使用 ADuser@domain.com 而不是 domain/ADuser 解决的

USE [master]
GO

EXEC master.dbo.sp_addlinkedserver @server = N'ADSI', @srvproduct=N'Active 
Directory Service Interfaces', @provider=N'ADSDSOObject', 
@datasrc=N'adsdatasource'

EXEC master.dbo.sp_addlinkedsrvlogin 
@rmtsrvname=N'ADSI',@useself=N'False',@locallogin=NULL,
@rmtuser=N'Domain/ADUser',@rmtpassword='########'
Run Code Online (Sandbox Code Playgroud)

错误:

消息 7321,级别 16,状态 2,第 1 行准备查询时出错“SELECT *
FROM 'LDAP://Domain.com/OU=Accounts,DC=Domain,DC=com' --WHERE objectClass = 'User ' " 用于针对链接服务器 "ADSI" 的 OLE DB 提供程序 "ADSDSOObject" 执行。

链接服务器到外部 LDAP 服务器

USE …
Run Code Online (Sandbox Code Playgroud)

sql-server windows linked-server sql-server-2012 active-directory

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

在这种情况下使用 WITH (NOLOCK) 安全吗?

设想

我有一个处理并发 SELECT 和 DELETE 的表。我的 SELECT 语句出现了一些死锁。我假设来自其他事务的 DELETE 正在获取排他锁并与 SELECT 的共享锁冲突。

细节

  • SQL Server 14.00.3281.6.v1
  • 在 AWS RDS 上运行

用例

  • 我的应用程序可以通过多种方式触发 SELECT。
  • 如果应用程序触发 DELETE,它将(总是)触发 SELECT 以检索反映 DELETE 效果的结果。

在并发 SELECT 和 DELETE 的情况下,它可能看起来像这样(在 MS Paint 中绘制,因为我试图变得专业......):

时间线图片

编辑:上面的“触发器”不是指实际的数据库触发器,而是指应用程序行为。

研究

我在 DBA Stack Exchange 上四处闲逛,发现我可以SELECT myTable WITH (NOLOCK)阻止共享锁。我正在考虑使用它,但我知道有很多警告和问题,所以我想验证我的决定或在必要时更换它。

我是 WITH (NOLOCK) 的新手,所以这是我从这个有用的网站学到的东西:

WITH (NOLOCK) 表提示检索行,而无需等待其他正在读取或修改相同数据的查询来完成其处理。

理由

这些报价来自同一个链接。在每一项下,我都描述了我的想法,得出结论认为该行为不会影响我。

通常,经常使用显式表提示被认为是一种应避免的不良做法。特别是对于NOLOCK表提示,读取未提交的数据,读完后可能会回滚,会导致Dirty read,在未提交的数据读取过程中读取正在修改或删除的数据时会出现这种情况,从而导致数据你读到的可能会有所不同,或者甚至从未存在过。

脏读:我认为我不需要关心这个,因为 SELECT 实际上并不是因为脏读而无效。任何导致脏读的 DELETE 都会触发一个新的 SELECT 来纠正最终结果。 我认为两个 SELECT 结果都是有效的,尽管一个只在几毫秒内有效。

WITH (NOLOCK) 表提示也会导致不可重复读取;当需要多次读取相同的数据并且在这些读取过程中数据发生变化时,就会发生这种读取。在这种情况下,您将阅读同一行的多个版本。

不可重复读:我的 SELECT 只有该表中的一个 SELECT 语句,所以我认为这不是问题。 …

sql-server deadlock concurrency nolock

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

由于 SQL Server 中没有 unsigned int,因此 -2,147,483,648 的标识种子对大表是否更有意义?

我刚刚想到默认的 Identity Seed 是 1。我知道有些表在某个时候会增长到数十亿。int.Min对于这些表,从(-2,147,483,648)开始不是更有意义吗?

这可能只是bigint在 4 年或 8 年内将您的密钥迁移到不同。可以足够相关。

这是常见的吗?感觉很奇怪。有什么我想念的吗?

sql-server identity

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

存储过程出错时为什么会提交部分事务?

我有一个存储过程,它首先声明一些变量,然后包含begin tran;在此之后它对提供的参数执行一些验证(并且每次提供的参数验证失败时都会增加错误计数)。如果没有错误计数,则继续执行 7 次插入。在此之后,它有commit tran;

最近我在列表中添加了第 8 个插入。隐式类型转换意味着某些插入的数据在插入时会被截断。这向 SSMS 屏幕抛出了一个错误,但我发现前 7 个插入已提交,而第 8 个显然没有完成。

我很欣赏我可以包含一个try ... catch块来处理错误,但如果一个显式begin tran;不能使整个工作块自主到commit,那么有什么意义呢?我错过了什么?

我知道我也许可以将我的程序调用包装在那个级别的事务中 - 但是有人可以解释发生了什么以及为什么begin tran当包含在程序主体中时似乎不受尊重吗?如果调用该过程开始一个隐式事务,那么 proc 中的错误步骤不应该回滚受 proc 影响的所有更改 - 即使没有明确包含begin tran在 proc 主体中?

sql-server stored-procedures transaction

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

数据库“管理员”是否应该能够深入研究运行时查询性能问题?

我承认每个人的经验和能力都是不同的。话虽如此,我想避免为 DBA 通过行动设定过高(或过低)的期望;似乎是“管理员”。

鉴于:

  • 我是一名深入研究 SQL Server 故障排除和性能问题的开发人员。晚上我拿着一桶爆米花看 Brent Ozar 的视频。
  • 一个有多个部门的公司,这个部门有大约 100 名团队成员
  • 许多客户的数据库有数百万行 ETL
  • 一个小型 DBA 团队,可以处理这些相同的客户。处理 HAG 问题、备份、恢复、为新客户或升级客户创建新部署。

我不是试图证明我自己的观点是正确的。我想调整我的意见或公司其他人的意见。

题:

鉴于上述情况,是否应该期望 DBA 只是一个“管理员”?这是你经常看到的吗?


我进入这部肥皂剧(请参阅我最近的其他问题)时,期望 DBA“有望”深入研究。我开始相信我误解了,我倾向于 DBA - 成为“管理员”。

我欢迎其他人的经验,也许还可以提供关于完善这个问题的建议。

sql-server career

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

SQL Server 不使用索引

我对为什么我的查询没有使用我认为是选择性索引的东西感到非常困惑。

我的模型由索赔、联系人和电话号码组成。每个索赔有 1 个联系人,每个联系人都有许多电话号码。索赔可以有状态,电话号码有类型。 简化模型

我在状态的 Claim 上添加了一个索引,它包括 ContactID。

create index Status on tClaim(Status) include (Name,ContactID)
Run Code Online (Sandbox Code Playgroud)

我在电话上为 ContactID 和类型添加了一个索引,其中包括号码。

create index ContactID_Type on tContactPhone(ContactID,Type) include (Number)
Run Code Online (Sandbox Code Playgroud)

我正在尝试编写一个查询,该查询返回状态为“赢得”的所有索赔以及索赔联系人的相应“家庭电话”。我已经尝试了 2 种方法。一种包括加入通讯录,另一种没有。两者都不会产生我期望的计划。

select 
    c.ID,
    c.Name,
    p.Number 
from
     tClaim c 
     left join tContactPhone p on
        c.ContactID=p.ContactID and p.Type='Home'
where
    c.Status = 'Won'

select 
    c.ID,
    c.Name,
    p.Number
from
     tClaim c
     inner join tContact co on  
        co.id=c.ContactID
     left join tContactPhone p on
        co.ID=p.ContactID and p.Type='Home'
where
    c.Status = 'Won'
Run Code Online (Sandbox Code Playgroud)

我回来的计划拒绝使用 tContactPhone.ContactID_Type。它建议按类型索引,这没有意义,因为它似乎没有 ContactId 选择性。

粘贴计划

这是我用来创建要测试的示例数据集的脚本。请注意我的实际数据集要大得多,命名得更好,并且有更多的字段;但这被提炼出来以复制我的情况 [AKA 我什至不喜欢命名约定和数据生成,但它完成了工作:)] …

index sql-server execution-plan cardinality-estimates sql-server-2019

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

嵌套 CTE 在某些情况下返回不正确的结果

好的,首先让我说我从以下方面得到了这个问题:

我试图帮助找出问题,但在尝试一步一步调试代码时被难住了。我知道这个问题是由于嵌套的 CTE(因为在调试过程中,如果你将每一步 aka cteX 转储到临时表中,就会获得正确的结果)但不知道它们是如何“在幕后”工作的,我无法在外面以一种明智的方式解释它“它不起作用哟。” 我怀疑这与编译器如何尝试在运行时同时评估它们有关,但没有更多上下文我不能肯定地说。

我的问题只是试图了解它们如何在幕后工作以及它与这种情况有何关系。现在我参与其中,我只想了解这个问题,以便将来可以与之交谈并同时学习一些有趣的东西。

在这里回答的人也可以在 SO 上交叉发布并在那里回答。

代码设置:

declare @t1 TABLE (ID varchar(max),Action varchar(max), DateTime datetime );
INSERT INTO @t1
Select *
from
(
VALUES 
('w2337','Open','2020-11-06 12:28:10.000'),
('w2337','Hold','2021-06-14 14:50:59.000'),
('w2337','Open','2021-06-14 14:51:26.000'),
('w2337','Hold','2021-06-15 14:50:59.000'),
('w2337','Open','2021-06-17 14:51:26.000'),
('w2337','Open','2021-06-18 14:51:26.000')

) t (ID, Action, DateTime);

with cte1 as (
select [ID],[Action],[DateTime]
,ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) as [RegIndex]
,DENSE_RANK () OVER (ORDER BY ID) as [Index by ID]
,ROW_NUMBER() OVER (PARTITION BY ID …
Run Code Online (Sandbox Code Playgroud)

sql-server cte

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

检查另一个会话的 IMPLICIT_TRANSACTIONS 设置

在 SQL Server 中,您可以IMPLICIT_TRANSACTIONS通过@@OPTIONS.

如何找到IMPLICIT_TRANSACTIONS另一个会话的值?

这绝对可以做到,因为 SQL Server Profiler 显示了这一点。

sql-server metadata

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