小编Ale*_*xei的帖子

始终将单个整数列作为主键的缺点是什么?

在我正在处理的一个 Web 应用程序中,所有数据库操作都是使用一些在实体框架 ORM 上定义的通用存储库进行抽象的。

但是,为了通用存储库的简单设计,所有涉及的表都必须定义一个唯一的整数(Int32在 C# 中,int在 SQL 中)。直到现在,这一直是桌上的PK,也是IDENTITY.

外键被大量使用,它们引用这些整数列。它们对于一致性和 ORM 生成导航属性都是必需的。

应用层通常会做以下操作:

  • 从表(*)加载初始数据-SELECT * FROM table
  • 更新-UPDATE table SET Col1 = Val1 WHERE Id = IdVal
  • 删除-DELETE FROM table WHERE Id = IdVal
  • 插入-INSERT INTO table (cols) VALUES (...)

不太频繁的操作:

  • 批量插入-BULK INSERT ... into table后跟 (*) 所有数据加载(以检索生成的标识符)
  • 批量删除- 这是一个正常的删除操作,但从 ORM 的角度来看是“庞大的”:DELETE FROM table where OtherThanIdCol = SomeValue …

database-design sql-server identity sql-server-2014

18
推荐指数
4
解决办法
3514
查看次数

有没有一种有效的方法来查看“字符串或二进制数据将被截断”的原因?

这是对这个问题的跟进。这也与微软的这个功能请求有关。

然而,许多年过去了,自从它被报道以来,有几个主要版本进入了市场。

问题: SQL Server 2017 是否提供任何机制来轻松找出此错误的根本原因?还是像大约 9 年前报告该问题时一样难以调查?

sql-server string sql-server-2017

13
推荐指数
1
解决办法
1788
查看次数

如何调查 BULK INSERT 语句的性能?

我主要是使用实体框架 ORM 的 .NET 开发人员。但是,因为我不想在使用 ORM失败,所以我试图了解数据层(数据库)中发生了什么。基本上,在开发过程中,我启动分析器并检查代码的某些部分根据查询生成了什么。

如果我发现一些非常复杂的事情(ORM 甚至可以从相当简单的 LINQ 语句中生成糟糕的查询,如果编写不仔细)和/或繁重(持续时间、CPU、页面读取),我会将它放入 SSMS 并检查其执行计划。

它适用于我的数据库知识水平。但是, BULK INSERT 似乎是一种特殊的生物,因为它似乎不会产生 SHOWPLAN

我将尝试说明一个非常简单的例子:

表定义

CREATE TABLE dbo.ImportingSystemFileLoadInfo
(
    ImportingSystemFileLoadInfoId INT NOT NULL IDENTITY(1, 1) CONSTRAINT PK_ImportingSystemFileLoadInfo PRIMARY KEY CLUSTERED,
    EnvironmentId INT NOT NULL CONSTRAINT FK_ImportingSystemFileLoadInfo REFERENCES dbo.Environment,
    ImportingSystemId INT NOT NULL CONSTRAINT FK_ImportingSystemFileLoadInfo_ImportingSystem REFERENCES dbo.ImportingSystem,
    FileName NVARCHAR(64) NOT NULL,
FileImportTime DATETIME2 NOT NULL,
    CONSTRAINT UQ_ImportingSystemImportInfo_EnvXIs_TableName UNIQUE (EnvironmentId, ImportingSystemId, FileName, FileImportTime)
)
Run Code Online (Sandbox Code Playgroud)

注意:表上没有定义其他索引

批量插入 (我在探查器中捕获的内容,仅一批)

insert bulk [dbo].[ImportingSystemFileLoadInfo] ([EnvironmentId] …
Run Code Online (Sandbox Code Playgroud)

sql-server execution-plan sql-server-2014 bulk-insert

12
推荐指数
2
解决办法
1万
查看次数

如果选择语句包含在 BEGIN TRAN ... COMMIT 中,是否有任何副作用?

我正在处理一个相当古老的 .NET 项目,并引入了一些新功能(在顶部),这些功能产生了以下副作用:所有生成的 SELECT(或组)都包含在BEGIN TRAN ... COMMIT语句中。

这听起来很愚蠢,但要摆脱它需要进行大量更改,而我负担不起。我的假设是这基本上意味着每组 SELECT 的小开销(应用程序和 SQL Server 之间的 BEGIN TRAN 和 COMMIT)。

我想知道是否还有更多内容(额外锁定?)。

问题:如果选择语句包含在 BEGIN TRAN ... COMMIT 中,是否有任何副作用?

sql-server transaction select sql-server-2016

7
推荐指数
1
解决办法
206
查看次数

如何减少标识值以避免整数溢出?

我有一些叶表(对它们没有 FK),其中有几十万条记录,用于使用实体框架 ORM 同步一些外部数据。这涉及一些 DELETE,然后是 BULK INSERT。

对于大多数表,一些旧值可能会永远保留,所以我不能将 SEQUENCEs 与 CYCLE 一起使用,正如其中一条评论中所建议的那样。

一种影响是身份值会随着时间的推移不断增加,我希望能够降低它们的值。

这个问题及其答案解释了无法更新标识值,即使identity_insert表的标识值已打开。

一种快速的方法是将所有数据传输到缓冲表并通过重命名执行切换。类似于以下内容:

-- ActiveDirectoryCache_bak is the table I want to reduce identity values for
-- ActiveDirectoryCache_bak_buffer is a buffer table that will be renamed to ActiveDirectoryCache_bak once data transfer is ready

begin tran
select min(UserId), count(1) from ActiveDirectoryCache_bak
DBCC CHECKIDENT ('ActiveDirectoryCache_bak', NORESEED);  

-- Min UserId = 100, Count = 176041
-- Checking identity information: current identity value '204558', current column value '204558'.    

select * …
Run Code Online (Sandbox Code Playgroud)

sql-server identity sql-server-2014

5
推荐指数
1
解决办法
1402
查看次数

使用持久表注入连接上下文信息

我正在开发一个应用程序,该应用程序具有多个严重依赖存储过程的遗留模块(没有 ORM,因此所有获取和数据持久性都是通过存储过程完成的)。

遗留模块的安全性依赖于SUSER_NAME()获取当前用户并应用安全规则。

我将其迁移为使用 ORM(实体框架),并且 SQL 连接器将使用通用用户连接到数据库(SQL Server),因此我必须向许多过程提供当前用户名。

为了避免 .NET 代码发生更改,我想到在建立新连接时以某种方式在上下文中“注入”当前用户:

CREATE TABLE dbo.ConnectionContextInfo 
(
    ConnectionContextInfoId INT NOT NULL IDENTITY(1, 1) CONSTRAINT PK_ConnectionContextInfo PRIMARY KEY,
    Created DATETIME2 NOT NULL CONSTRAINT DF_ConnectionContextInfo DEFAULT(GETDATE()),
    SPID INT NOT NULL,
    AttributeName VARCHAR(32) NOT NULL, 
    AttributeValue VARCHAR(250) NULL,
    CONSTRAINT UQ_ConnectionContextInfo_Info UNIQUE(SPID, AttributeName)
)
GO
Run Code Online (Sandbox Code Playgroud)

当连接打开(或重用,因为使用连接池)时,将使用以下命令:

exec sp_executesql N'
    DELETE FROM dbo.ConnectionContextInfo WHERE SPID = @@SPID AND AttributeName = @UsernameAttribute;
    INSERT INTO dbo.ConnectionContextInfo (SPID, AttributeName, AttributeValue) VALUES (@@SPID, @UsernameAttribute, @Username);
',N'@UsernameAttribute nvarchar(8),@Username nvarchar(16)',@UsernameAttribute=N'Username',@Username=N'domain\username'
go …
Run Code Online (Sandbox Code Playgroud)

sql-server connections

4
推荐指数
1
解决办法
3553
查看次数

数据库文件 ..._log 的最大文件大小设置为 x MB。如果空间不足,数据库将停止工作

我正在使用BrentOzarSQL Server First Responder Kit,因为我属于“管理 Microsoft SQL Server 的开发人员。如果它们出现故障或缓慢是您的错”。

运行的警告之一sp_blitz如下:

[DB] 数据库文件 DB_log 的最大文件大小设置为 10240MB。如果空间不足,即使可能有可用的驱动器空间,数据库也会停止工作。

日志文件位于与操作系统不同的驱动器上,我确实限制了它们的增长。所有数据库都有简单的恢复模式(大部分数据是通过复制和ETL自动获取的,从上次备份中恢复对我来说就足够了)。

该数据库有大约 20GB 的数据。

问题:如果恢复模式不强制我备份日志,数据库如何停止工作?

sql-server transaction-log sql-server-2014 sp-blitz

3
推荐指数
1
解决办法
384
查看次数

可以将 SQL Server 配置为不以静默方式截断 VARCHAR 值吗?

在像某些情况下这一个,SQL Server将默默地截断(N)VARCHAR值,导致严重的数据丢失时,错误地声明变量。

问题:可以将 SQL Server 配置为不以静默方式截断 VARCHAR 值吗?(并发出错误/引发异常)

sql-server sql-server-2014

3
推荐指数
1
解决办法
4994
查看次数

SQL Server 中的休眠连接需要多少资源?

我们的一位 DBA 向我们的团队抱怨说,他注意到大约有十几个睡眠连接实际上是永久性的。它们中的每一个都表示一个非常短的查询(单个记录中的单个记录通过其集群 PK 过滤返回)。

我的假设是,原因是 ADO.NET 连接池的使用以及经常进行相同查询的应用程序。

我试图找出这些睡眠连接是否会对 SQL Server 性能产生有意义的影响。默认情况下,ADO.NET 连接池的连接数限制为 100 个,因此我的假设是十几个休眠连接应该可以忽略不计。

我只能在这个线程中找到信息:

每次睡眠的最低成本约为 32kb RAM - 非常非常适中!

CPU 开销可能会产生一些微小的额外成本,但即使对于 10,000 个会话,也几乎无法检测到。

在会话/连接开销方面,SQL Server 表现得非常好!

这些信息准确吗?

performance sql-server connections sql-server-2017

3
推荐指数
1
解决办法
1274
查看次数

删除大部分数据后缩小+重新索引是否不好?

我有一个在 SQL Server 2017 Express 上运行的测试环境,它只使用最近的数据(一个作业每月一次删除超过三个月的数据)。

该作业执行以下操作:

  1. 使用 while 循环,它删除了超过三个月的数据
  2. 缩小数据库,如果其大小高于某个阈值
  3. 重新索引所有表

这篇文章描述了由于索引碎片而缩小数据库是多么糟糕,以及为什么重新索引也需要额外的空间。

上次运行从 9GB 数据库开始。删除需要 3-4 分钟,重新索引大约需要 30 秒。数据库减少到大约 5GB。

由于这是一个测试环境,我可以承受这种停机时间而不会出现任何问题。

问题:在删除了很大一部分数据后收缩 + 重新索引是不是很糟糕?

index sql-server shrink sql-server-2017

2
推荐指数
1
解决办法
1150
查看次数