标签: sql-server-2016

Alwayson AG 租约超时和健康检查超时

我们有一个带有两个实例的物理 SQL Server 2016 Enterprise SP2,每个实例包含一个 AG。有时会发生一个AG去resolve(没有failover),集群资源在500ms后自动重启,然后一切又重新上线。但是我还没有找到原因。

当我检查错误日志时,我看到以下条目:

日期 14/04/2019 23:35:37
SQL Server 托管可用性组“AG_PROD”在租用超时期限内未收到来自 Windows Server 故障转移群集的进程事件信号。

日期 14/04/2019 23:35:37
SQL Server 托管可用性组“AG_PROD”在租用超时期限内未收到来自 Windows Server 故障转移群集的进程事件信号。

日期 14/04/2019 23:35:14
SQL Server 在数据库 ID 6 中的文件 [e:\sqlData\db.mdf] 上遇到了 1 次 I/O 请求需要超过 15 秒才能完成。操作系统文件句柄是 0x0000000000001128。最新的long I/O的偏移量为:0x00010de65c0000

日期 14/04/2019 23:33:10
BACKUP DATABASE WITH DIFFERENTIAL 在 61.045 > 秒(6.585 MB/秒)内成功处理了 51459 页。

如您所见,有一个 IO 请求需要的时间超过 15 秒,我希望能在*_SQLDIAG_*.xel文件中找到它,但此处未发现任何错误。

当我检查集群日志时,我发现以下内容:

2019/04/14-23:35:09.430 INFO [NM] 收到来自客户端地址 SQL1 的请求。
2019/04/14-23:35:09.444 INFO [NM] 收到来自客户端地址 SQL1 的请求。
2019/04/14-23:35:09.459 …

clustering database-internals availability-groups sql-server-2016

6
推荐指数
0
解决办法
5179
查看次数

如何查找计算列中是否引用了列?

我正在尝试批量重新输入列。这意味着首先删除并重新创建它们所属的任何约束。

我发现这些约束引用的列

  • 外键,
  • 主键,
  • 索引,
  • 检查约束,
  • 规则,
  • 默认约束。

但我找不到计算列。

我已经研究过INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE,但它不包括计算列。

还有sys.computed_columnswhich 显示定义,但不以可搜索的方式列出列。

我还有其他地方可以看吗?如果 SQL Server 可以弄清楚依赖关系,我想我也可以。

sql-server t-sql dmv system-tables sql-server-2016

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

兼容级别 80 和 100 之间的可变长度字符串问题

在我当前的企业中,我遇到了大量与特定场景相关的问题。

我们有一个 SQL Server 2008,我们想迁移到 SQL Server 2016,所以我们将兼容性从 80 迁移到 100,但是我们的一些存储过程有问题,如下代码所示:

CREATE TABLE #PRUEBA (texto1 char(30), condicion char(30)) 
INSERT INTO  #PRUEBA VALUES ('PFI','1') 
INSERT INTO #PRUEBA VALUES ('CFI','2') 
SELECT 
    CASE
        WHEN condicion= '1' THEN texto1 
        ELSE 'TFI'
    END 
FROM  #PRUEBA 
DROP TABLE #PRUEBA
Run Code Online (Sandbox Code Playgroud)

兼容性 -> 80

'PFI                           ' -> char of 30 length 
'TFI                           ' -> char of 30 length
Run Code Online (Sandbox Code Playgroud)

兼容性 -> 90

'PFI                           ' -> varchar of 30 length
'TFI'                            -> varchar of 3 length
Run Code Online (Sandbox Code Playgroud)

兼容性 -> 100

'PFI …
Run Code Online (Sandbox Code Playgroud)

sql-server-2008 sql-server varchar sql-server-2016 compatibility-level

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

如何强制 SQL Server 通过视图使用我的空间索引?

我有一些表,其中包含存储为 lat long 对的属性的事务。(然后在我的示例架构中有更多的列和数据点)。

一个常见的请求是查找特定点 X 英里范围内发生的交易,并且只检索附近每个房产发生的 5 个最近的交易。

为了完成这项工作,我决定添加一个视图来封装最新的逻辑:

create or alter view dbo.v_example
with schemabinding as
select example_id
      ,transaction_dt
      ,latitude
      ,longitude
      ,latlong
      ,most_recent= iif(row_number() over (partition by latitude,longitude order by transaction_dt desc) < 5,1,null)
from dbo.example;
Run Code Online (Sandbox Code Playgroud)

所以一个查询可能看起来像这样:

create or alter view dbo.v_example
with schemabinding as
select example_id
      ,transaction_dt
      ,latitude
      ,longitude
      ,latlong
      ,most_recent= iif(row_number() over (partition by latitude,longitude order by transaction_dt desc) < 5,1,null)
from dbo.example;
Run Code Online (Sandbox Code Playgroud)

不幸的是,当我通过视图查询时,SQL Server 不想使用空间索引。如果我删除schemabinding并尝试在视图上添加提示,我会发现查询处理器无法创建计划。

如何封装逻辑并仍然让它使用我的空间索引?

这是一个带有示例数据和计划形状的 db<>fiddle

该表要大得多,扫描它然后进行聚集索引查找然后逐点查找要慢得多。

sql-server spatial sql-server-2016

6
推荐指数
1
解决办法
260
查看次数

使用 SQL 作业进行备份时是否可以使数据库脱机?

我有一个场景,我必须生成数据库的备份(SQL Server 2008)并恢复到新服务器(SQL Server 2016)。在采取备份数据时,无论如何都不应更改。所以我有两个选择来做到这一点,但我不确定它会如何工作。(一切都只使用 SQL 作业。)

  1. 设置只读数据库并恢复到新的数据库服务器。

    ? 是否可以在新服务器上恢复只读数据库?目标服务器已经有一个同名的读写(在线)数据库。

  2. 设置离线数据库并恢复到新的数据库服务器。

    ? 是否可以在新服务器中恢复离线数据库?目标服务器已经有一个同名的在线(读写)数据库。

sql-server backup sql-server-2008-r2 sql-server-2016

6
推荐指数
2
解决办法
2107
查看次数

多个join的SQL查询执行计划的逻辑顺序

我知道执行 SQL 查询的逻辑顺序是:

FROM
ON
JOIN
WHERE
GROUP BY
WITH CUBE or WITH ROLLUP
HAVING
SELECT
DISTINCT
ORDER BY
TOP
Run Code Online (Sandbox Code Playgroud)

如果查询中有多个连接会发生什么,例如,如果我们有这样的查询:

SELECT *
FROM user_branch T1
INNER JOIN dimcustomer2 T2
   ON T1.BRANCH_CODE = T2.BRANCH_CODE
INNER JOIN customer_guarantee T3
   ON T3.CUSTOMER_NUM = T2.CUSTOMER_NUM
Run Code Online (Sandbox Code Playgroud)

一些示例数据:

customer_guarantee:    CUSTOMER_NUM      BRANCH_CODE
                      -------------------------------
                           A                X
                           B                X
                           C                Y
                           D                Z



 user_branch:           USER_ID          BRANCH_CODE    
                      --------------------------------
                           U1               Y



 dimcustomer2:         CUSTOMER_NUM      BRANCH_CODE      
                      --------------------------------
                           A                Y
                           B                Y
                           C                Y
                           D                Z
Run Code Online (Sandbox Code Playgroud)

这将如何执行?哪个连接会先执行?如果查询中有不同类型的连接怎么办?在这种情况下执行连接的顺序是什么?提前致谢。

query t-sql sql-server-2016

6
推荐指数
2
解决办法
3983
查看次数

SQL Server 用户无法查看所有登录信息

我有一个 SQL Server 2016 实例,我刚刚注意到某些用户的某些用户登录名未列出。例如,如果我执行此查询:

select count(*) FROM sys.database_principals a where type = 'U'
Run Code Online (Sandbox Code Playgroud)

我收到的计数是1348. 但是如果我执行这个查询:

execute as user = 'some_user';
select count(*) FROM sys.database_principals a where type = 'U';
revert;
Run Code Online (Sandbox Code Playgroud)

我收到的计数为92,这意味着存在1256上述用户看不到的用户。如果我授予用户db_accessadmin数据库角色成员资格,那么他们就可以看到1348从上述查询返回的所有用户。但我不想授予db_accessadmin所有用户,因为这提供的访问权限比我想要授予的要多得多。

我已将显示的 92 个用户之一的属性与未显示的用户的属性进行了比较,但我没有注意到任何看起来允许列出该用户的属性。

我该如何允许所有用户都列在对database_principals 的查询中?

sql-server permissions sql-server-2016

6
推荐指数
1
解决办法
6096
查看次数

为什么 sys.dm_exec_query_stats 中缺少大多数缓存计划?

我试图了解 SQL Server 2016 SP3 系统上缓存元数据的一些执行计划,但我无法将我所看到的内容与文档相一致。

文档sys.dm_exec_cached_plans说它包含:

SQL Server 缓存每个查询计划的一行,以加快查询执行速度。

在我正在观察的系统上,该视图现在有 41,283 行。其中绝大多数(37,594 行)是cacheobjtype =“Compiled Plan”和objtype =“Adhoc”。

文档sys.dm_exec_query_stats说它包含:

缓存计划中每个查询语句一行,行的生命周期与计划本身相关。当从缓存中删除计划时,相应的行将从该视图中删除。

我预计此视图中至少有 37,594 行(每个缓存计划一个,如果某些缓存计划有多个语句,则可能更多)。但是,该视图总共有 6,867 行。

这种差异是如此之大,以至于我必须假设我误解了这些视图中应该包含的内容。

sys.dm_exec_query_stats有人可以帮助我理解为什么与 相比 的行数如此之少吗sys.dm_exec_cached_plans

我尝试在 上将表内部连接在一起plan_handle,唯一的匹配是 1:1 - 换句话说,有数以万计的缓存计划,没有“查询统计”行。

我还认为差异可能是由sys.dm_exec_procedure_stats或中的许多行来解释的sys.dm_exec_trigger_stats,但事实并非如此(分别为 93 行和 2 行)。

对于任何对这个问题的“为什么”感到好奇的人,我试图查看缓存中的各种计划有多旧,并且我不确定除了加入和sys.dm_exec_query_stats检查之外还有什么方法可以做到这一点creation_time


以下是我用来获取上面引用的数字的查询:

-- total cached plans
SELECT COUNT_BIG(*) AS total_cached_plans
FROM sys.dm_exec_cached_plans decp

-- totals by type
SELECT decp.cacheobjtype, decp.objtype, COUNT_BIG(*) AS plan_count
FROM sys.dm_exec_cached_plans …
Run Code Online (Sandbox Code Playgroud)

sql-server execution-plan plan-cache sql-server-2016

6
推荐指数
1
解决办法
878
查看次数

DateTime2 和页面预期寿命 (PLE)

据我了解,当您在表上定义列时,您就定义了其精度。该精度占用 1 个字节并存储在列级别。如果您使用 5 或更高的精度,则 DateTime2 列每行将占用 8 个字节。(精度不存储在行级别。)

但是,当您将相同的 DateTime2 转换为 VarBinary 时,它将占用 9 个字节。这是因为它需要存储在列级别的精度字节。

我很好奇这与 DateTime2 存储在内存中有何关系。假设内存中有 1,000,000 个 DateTime2(每个的精度为 5 或更高)。它会占用 8,000,000 字节内存还是 9,000,000 字节内存?

基本上,我想知道默认精度的 DateTime2 是否会比普通的 DateTime 对页面预期寿命造成更大的压力?

sql-server datetime sql-server-2016 page-life-expectancy

6
推荐指数
2
解决办法
561
查看次数

查询存储计划强制失败,NO_PLAN 取决于过滤器运算符在计划中的位置

我有一个查询,我在查询存储中强制执行一个计划(该计划是为此查询编译的 SQL Server)如果我在强制执行该计划后立即运行该查询,NO_PLAN尽管数据库没有发生任何更改,但我会得到last_force_failure_reason_desc。我可以成功地对同一查询强制执行不同的计划

这个问题可以用下图来说明:

创建我们的测试数据库

USE [master]
CREATE DATABASE NO_PLAN
ALTER DATABASE [NO_PLAN] SET QUERY_STORE = ON
ALTER DATABASE [NO_PLAN] SET QUERY_STORE (OPERATION_MODE = READ_WRITE, QUERY_CAPTURE_MODE = ALL)
GO

USE NO_PLAN
GO
IF EXISTS (SELECT 1 FROM sys.tables WHERE name = 'MyTableA') DROP TABLE MyTableA
IF EXISTS (SELECT 1 FROM sys.tables WHERE name = 'MyTableB') DROP TABLE MyTableB

/* create  our tables */
CREATE TABLE [dbo].[MyTableA](
    [Column1] VARCHAR(50) NULL ,
    [Column2] VARCHAR(255) NULL ,
    [Column3] INT NULL , …
Run Code Online (Sandbox Code Playgroud)

sql-server hints execution-plan sql-server-2016 query-store

6
推荐指数
1
解决办法
272
查看次数