标签: sql-server

SQL Server:涵盖所有列的索引?

我们的团队继承了一个应用程序和相关的数据库。以前的开发人员似乎强制执行了一个规则,即每个表上的每个索引都有一个 INCLUDE 子句,以始终添加不属于键的每一列。这些表平均有两到五个索引或唯一约束以及外键。

目的似乎是提高 SELECT 性能,无论向数据库抛出什么查询,因为访问是通过 ORM 进行的,默认情况下(但并非总是)检索所有列。我们预计这样做的副作用是增加了存储需求(可能显着增加)和 INSERT/UPDATE/DELETE 的额外开销时间。

问题是,这是一个明智的策略吗?我们的团队有使用 SQL Server 的历史,但没有成员认为自己是其内部行为的专家(尽管有人提出问题,如果这种策略是最佳的,现在不是默认吗?)。我们应该期待哪些其他副作用(数据库服务器 CPU/内存/TempDB 使用等),或者我们上面的一些假设是不正确的?

此外,该应用程序可以安装到本地 SQL Server(自 2012 年以来的版本)以及 Azure SQL 中——我们是否应该为两者之间的任何差异做好准备,或者因此对 Azure 产生额外的副作用方法?

sql-server azure-sql-database sql-server-2012 sql-server-2014 sql-server-2016

9
推荐指数
2
解决办法
1153
查看次数

SQL每隔几分钟从缓冲区缓存中转储所有页面

我有一个运行多个数据库的 SQL2012 SP4 节点。

服务器有 20GB 可用内存,14GB 分配给 SQL(盒子上没有其他东西在运行)。

每隔几分钟,SQL 就会转储整个缓冲区缓存。页面预期寿命为零,缓冲区缓存描述符显示缓存中没有任何内容。

我查看了资源监视器通知,通知每隔几毫秒从高/稳定/低反弹:

RESOURCE_MEMPHYSICAL_HIGH RESOURCE_MEM_STEADY RESOURCE_MEMPHYSICAL_LOW

时间戳相隔几毫秒。PLE 本质上是一种锯齿图案。

我以前在 SQL2012 SP1 和这个问题中看到过这种情况:

未使用缓冲区缓存中的 SQL Server 2012 空闲页

似乎是一个类似的问题,虽然我已经更新到 SP4。

我试过为服务帐户打开 LPIM,我试过搞乱最大内存设置。降低最大内存似乎导致缓冲区缓存更频繁地清空。

关于下一步要检查什么的任何想法?

服务器工作负载实际上什么都没有(我正在浏览 ERP 系统中的项目列表,在缓存再次下降之前它达到了大约 40-50MB)。

这很有趣,因为我从 SP1 升级来尝试解决这个问题 - 那里的缓存达到了大约 500MB。从那以后,我将最大内存设置降低到 14GB,这似乎使情况变得更糟。

我想知道 Windows 是否会恐慌并在 SQL 处抛出错误的内存压力通知 - 因此将最大内存设置为无界的服务器似乎运行正常,但从未填充超过几百 MB 的缓存 - 但现在它勉强达到50...

更多信息:对于那些问

核心数: 4

数据库大小: 80GB

错误日志显示: A significant part of sql server process memory has been paged out. This may result in a performance degradation. Duration: 0 …

sql-server memory cache sql-server-2012

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

在 SQL Server 中,并行性如何改变内存授予?

我听说过关于并行选择查询的内存授予的相互矛盾的事情:

  • 内存授权乘以 DOP
  • 记忆补助除以 DOP

是哪个?

sql-server parallelism memory-grant

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

如何防止 SQL 文件打开 SSMS 17.9.1 的新实例?

概要

这不是一个新问题,互联网上有几种解决方案

问题

当您双击一个.sql文件时,将打开一个新的 SSMS 实例。在安装新的 SQL Server Management Studio (SSMS 17.9.1) 之前,我没有遇到这个问题。

我试过的

  • 此页面列出了几个建议更改注册表和文件关联以及重新安装 SSMS 的解决方案。没有一个工作。
  • 这个与上一个链接几乎相同。(SO 比那些论坛好多了。)
  • 此处显示注册表更改以及出色的屏幕截图。我添加了,"%1"但这没有任何区别。
  • SO 上提到的建议也不起作用。
  • DBA 上,主要是在谈论提高权限,而我的情况并非如此。

解决方法

是的,我知道这些解决方法:

  • Ctrl + O
  • .sql文件拖到 SSMS

不是在寻找解决方法。

我的环境

即使使用新的 SSMS 17.9.1(版本:14.0.17289.0),我仍然指向 SQL Server 2016 (13.0.5233.0)。以前,我使用 SSMS June 2016(版本:13.0.15000.23)和相同的 SQL Server (13.0.5233.0)。

由于许可,我没有以管理员身份运行任何应用程序。


此处列出SQL Server 版本。

此处列出SQL Server Management Studio 版本。

sql-server ssms sql-server-2016

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

取消旋转单行时如何摆脱无用的并行分支?

考虑以下查询,该查询对少量标量聚合进行了反透视:

SELECT A, B
FROM (
    SELECT 
      MAX(CASE WHEN ID = 1 THEN 1 ELSE 0 END) VAL1
    , MAX(CASE WHEN ID = 2 THEN 1 ELSE 0 END) VAL2
    , MAX(CASE WHEN ID = 3 THEN 1 ELSE 0 END) VAL3
    , MAX(CASE WHEN ID = 4 THEN 1 ELSE 0 END) VAL4
    , MAX(CASE WHEN ID = 5 THEN 1 ELSE 0 END) VAL5
    , MAX(CASE WHEN ID = 6 THEN 1 ELSE 0 END) VAL6
    , MAX(CASE …
Run Code Online (Sandbox Code Playgroud)

sql-server parallelism execution-plan sql-server-2017

9
推荐指数
2
解决办法
480
查看次数

显然,我的 CLR 汇编函数导致死锁?

我们的应用程序需要与 Oracle 数据库或 Microsoft SQL Server 数据库同样良好地工作。为了促进这一点,我们创建了一些 UDF 来统一我们的查询语法。例如,SQL Server 有 GETDATE() 而 Oracle 有 SYSDATE。它们执行相同的功能,但它们是不同的词。我们为两个平台编写了一个名为 NOW() 的包装器 UDF,它将相关的平台特定语法包装在一个公共函数名称中。我们还有其他这样的功能,其中一些本质上什么都不做,只是为了同质化而存在。不幸的是,这对 SQL Server 来说是有代价的。内联标量 UDF 对性能造成严重破坏并完全禁用并行性。作为替代方案,我们编写了 CLR 汇编函数来实现相同的目标。当我们将其部署到客户端时,他们开始经常遇到死锁。这个特定的客户端正在使用复制和高可用性技术,我想知道这里是否存在某种交互。我只是不明白如何引入 CLR 函数会导致这样的问题。作为参考,我已经包含了原始标量 UDF 定义以及 C# 中的替换 CLR 定义及其 SQL 声明。如果有帮助,我也可以提供死锁 XML。

原始UDF

CREATE FUNCTION [fn].[APAD]
(
    @Value VARCHAR(4000)
    , @tablename VARCHAR(4000) = NULL
    , @columnname VARCHAR(4000) = NULL
)

RETURNS VARCHAR(4000)
WITH SCHEMABINDING
AS

BEGIN
    RETURN LTRIM(RTRIM(@Value))
END
GO
Run Code Online (Sandbox Code Playgroud)

CLR 汇编函数

[SqlFunction(IsDeterministic = true)]
public static string APAD(string value, string tableName, string columnName)
{ …
Run Code Online (Sandbox Code Playgroud)

sql-server deadlock functions sql-clr

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

删除自动创建的 NT AUTHORITY 和 NT SERVICE 帐户

所以我最近转移了工作——我在我们的新 SQL Server 安装的构建脚本中发现的一段代码如下。

IF EXISTS ( SELECT  *
            FROM    [sys].[syslogins]
            WHERE   [name] = N'NT AUTHORITY\SYSTEM' )
    BEGIN
        DROP LOGIN [NT AUTHORITY\SYSTEM];
    END

IF EXISTS ( SELECT  *
            FROM    [sys].[syslogins]
            WHERE   [name] = N'NT SERVICE\SQLWriter' )
    BEGIN
        DROP LOGIN [NT SERVICE\SQLWriter];
    END

IF EXISTS ( SELECT  *
            FROM    [sys].[syslogins]
            WHERE   [name] = N'NT SERVICE\Winmgmt' )
    BEGIN
        DROP LOGIN [NT SERVICE\Winmgmt];
    END
GO
Run Code Online (Sandbox Code Playgroud)

默认情况下,这些帐户是在 SQL Server 安装过程中创建的。

是否建议删除上述登录?这会导致任何副作用吗?这些登录有什么用?

我阅读了能否删除 NT SERVICE\SQLWriter 和 NT SERVICE\Winmgmt 登录名?但这还不够具体-我可以看到它们的用途,但除此之外很少见。他们需要系统管理员访问权限吗?等等。

例如(取自配置 Windows 服务帐户和权限 …

security sql-server sql-server-2016

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

只读副本上的长时间运行查询,在主副本上需要一些时间

我有一个 4 节点 AG 设置,如下所示:

所有节点的VM硬件配置:

  • Microsoft SQL Server 2017 企业版 (RTM-CU14) (KB4484710)
  • 16 个 vCPU
  • 356 GB RAM(这个故事很长……)
  • 最大并行度:1(根据应用程序供应商的要求)
  • 并行性的成本阈值:50
  • 最大服务器内存 (MB):338944 (331 GB)

AG配置:

  • 节点 1:主节点或同步提交非可读辅助节点,配置为自动故障转移
  • 节点 2:主节点或同步提交非可读辅助节点,配置为自动故障转移
  • 节点 3:具有异步提交的可读辅助集,配置为手动故障转移
  • 节点 4:具有异步提交的可读辅助集,配置为手动故障转移

有问题的查询:

这个查询没有什么特别疯狂的地方,它提供了应用程序内各个队列中未完成工作项的摘要。您可以从下面的执行计划链接之一中查看代码。

主节点上的执行行为:

在 Primary 节点上执行时,执行时间一般在 1 秒左右。这是执行计划,以下是从主节点的 STATISTICS IO 和 STATISTICS TIME 捕获的统计信息:

(347 rows affected)
Table 'Worktable'. Scan count 647, logical reads 2491, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table …
Run Code Online (Sandbox Code Playgroud)

performance sql-server availability-groups sql-server-2017 query-performance

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

STATISTICS IO 输出是否包括版本存储读取?

SQL Server 有一个选项SET STATISTICS IO ON可以显示查询的逻辑和物理页读取次数。这些统计信息是否包括 SNAPSHOT 和 RCSI 查询的版本存储读取?

sql-server tempdb-version-store

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

在提交之前,SQL Server 是否允许(使可见)在事务中的 DDL 到事务?

在 PostgreSQL 中,我可以创建一个包含一些测试数据的表,然后在事务中将其迁移到不同类型的新列,从而导致一个表重写COMMIT

CREATE TABLE foo ( a int );
INSERT INTO foo VALUES (1),(2),(3);
Run Code Online (Sandbox Code Playgroud)

其次是,

BEGIN;
  ALTER TABLE foo ADD COLUMN b varchar;
  UPDATE foo SET b = CAST(a AS varchar);
  ALTER TABLE foo DROP COLUMN a;
COMMIT;
Run Code Online (Sandbox Code Playgroud)

但是,Microsoft 的 SQL Server 中的相同内容似乎会产生错误。比较这个工作db fiddle,其中ADD(列)命令在事务之外,

-- txn1
BEGIN TRANSACTION;
  ALTER TABLE foo ADD b varchar;
COMMIT;

-- txn2
BEGIN TRANSACTION;
  UPDATE foo SET b = CAST( a AS varchar );
  ALTER TABLE …
Run Code Online (Sandbox Code Playgroud)

sql-server transaction ddl sql-server-2017

9
推荐指数
2
解决办法
908
查看次数