标签: sql-server

为什么优化器会选择聚集索引 + 排序而不是非聚集索引?

给出下一个例子:

IF OBJECT_ID('dbo.my_table') IS NOT NULL
    DROP TABLE [dbo].[my_table];
GO

CREATE TABLE [dbo].[my_table]
(
    [id]    int IDENTITY (1,1)  NOT NULL PRIMARY KEY,
    [foo]   int                 NULL,
    [bar]   int                 NULL,
    [nki]   int                 NOT NULL
);
GO

/* Insert some random data */
INSERT INTO [dbo].[my_table] (foo, bar, nki)
SELECT TOP (100000)
    ABS(CHECKSUM(NewId())) % 14,
    ABS(CHECKSUM(NewId())) % 20,
    n = CONVERT(INT, ROW_NUMBER() OVER (ORDER BY s1.[object_id]))
FROM 
    sys.all_objects AS s1 
CROSS JOIN 
    sys.all_objects AS s2
GO

CREATE UNIQUE NONCLUSTERED INDEX [IX_my_table]
    ON [dbo].[my_table] …
Run Code Online (Sandbox Code Playgroud)

sql-server sql-server-2012 nonclustered-index

11
推荐指数
2
解决办法
658
查看次数

系统运行状况中有“sql_exit_invoked”是什么意思?

我的其中一台 SQL Server 2016 Standard 服务器出现问题。我有 8 台生产服务器,这是唯一一台在日志中没有任何痕迹的情况下随机崩溃的服务器。

我在其上启用了 system_health。我注意到我在系统健康女巫中有一行是“sql_exit_invoked”。

system_health_sql_exit_invoked

我正在尝试查找有关该行的更多信息。这是什么意思?我在互联网上找到的唯一信息是它在调用 SQLExit() 时发生,并且它只从 SQL 2012 开始记录。(链接在 msdn 网站上可用)

sql_exit_description

所以我的问题是:我应该担心在我的日志中看到这个吗?我只在我有问题的服务器上发现了这一点,而在其他 7 台服务器上都没有。(都是SQL Server 2016标准版)

有人可以给我更多关于这方面的信息吗?

sql-server extended-events sql-server-2016

11
推荐指数
1
解决办法
280
查看次数

在 JOIN 子句中使用 OR 时出现奇怪的查询计划 - 对表中的每一行进行持续扫描

我正在尝试生成一个示例查询计划来说明为什么联合两个结果集比在 JOIN 子句中使用 OR 更好。我写的一个查询计划让我很难过。我正在使用 StackOverflow 数据库和 Users.Reputation 上的非聚集索引。

查询计划图片 查询是

CREATE NONCLUSTERED INDEX IX_NC_REPUTATION ON dbo.USERS(Reputation)
SELECT DISTINCT Users.Id
FROM dbo.Users
INNER JOIN dbo.Posts  
    ON Users.Id = Posts.OwnerUserId
    OR Users.Id = Posts.LastEditorUserId
WHERE Users.Reputation = 5
Run Code Online (Sandbox Code Playgroud)

查询计划位于https://www.brentozar.com/pastetheplan/?id=BkpZU1MZE,我的查询持续时间为 4:37 分钟,返回 26612 行。

我以前从未见过从现有表创建这种类型的常量扫描 - 我不熟悉为什么对每一行都运行常量扫描,而常量扫描通常用于用户输入的单行例如 SELECT GETDATE()。为什么用在这里?我非常感谢阅读此查询计划的一些指导。

如果我将 OR 拆分为 UNION,它会生成一个标准计划,运行 12 秒,返回相同的 26612 行。

SELECT Users.Id
FROM dbo.Users
    INNER JOIN dbo.Posts
       ON Users.Id = Posts.OwnerUserId
WHERE Users.Reputation = 5
UNION 
SELECT Users.Id
FROM dbo.Users
    INNER JOIN dbo.Posts
       ON …
Run Code Online (Sandbox Code Playgroud)

sql-server execution-plan sql-server-2017

11
推荐指数
1
解决办法
579
查看次数

为什么我会得到从 Int / Smallint 到 Varchar 的隐式转换,它真的会影响基数估计吗?

我正在尝试对实际执行计划使用显示计划分析 (SSMS) 来解决执行缓慢的查询。分析工具指出,在计划中的几个地方,对行数的估计与返回的结果不一致,并进一步给了我一些隐式转换警告。

我不明白这些 int 到 Varchar 的隐式转换 - 引用的字段不是查询中任何参数/过滤器的一部分,并且在所有涉及的表中,列数据类型是相同的:

我收到以下 CardinalityEstimate 警告:

表达式中的类型转换 (CONVERT_IMPLICIT(varchar(12),[ccd].[profileid],0)) 可能会影响查询计划选择中的“CardinalityEstimate”——这个字段在我的数据库中到处都是整数

表达式中的类型转换 (CONVERT_IMPLICIT(varchar(6),[ccd].[nodeid],0)) 可能会影响查询计划选择中的“CardinalityEstimate”——这个字段在我的数据库中到处都是 smallint

表达式中的类型转换 (CONVERT_IMPLICIT(varchar(6),[ccd].[sessionseqnum],0)) 可能会影响查询计划选择中的“CardinalityEstimate”——这个字段在我的数据库中到处都是 smallint

表达式中的类型转换 (CONVERT_IMPLICIT(varchar(41),[ccd].[sessionid],0)) 可能会影响查询计划选择中的“CardinalityEstimate”——这个字段在我的数据库中到处都是小数

[编辑]这里是查询和实际执行计划供参考 https://www.brentozar.com/pastetheplan/?id=SysYt0NzN

和表定义..

/****** Object:  Table [dbo].[agentconnectiondetail]    Script Date: 1/10/2019 9:10:04 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[agentconnectiondetail](
    [sessionid] [decimal](18, 0) NOT NULL,
    [sessionseqnum] [smallint] NOT NULL,
    [nodeid] [smallint] NOT NULL,
    [profileid] [int] NOT NULL,
    [resourceid] [int] NOT NULL,
    [startdatetime] [datetime2](7) NOT NULL,
    [enddatetime] [datetime2](7) NOT NULL, …
Run Code Online (Sandbox Code Playgroud)

sql-server execution-plan type-conversion cardinality-estimates sql-server-2017

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

为什么只能删除当前数据库中的一个 SQL Server 视图?

刚刚注意到这一点,并且很难想出一个技术原因。

可以使用三个部分名称删除表,但视图仅限于两个部分名称。

这背后的原因是什么?

sql-server view

11
推荐指数
1
解决办法
249
查看次数

如何“自我审核”组织中的所有 SQL Server 许可证?

所以我在一个不错的非营利组织开始了一份新工作,该组织已经存在了几十年。它们有各种各样的 SQL Server 版本(例如:2005 Express 到 2016 SP2 Enterprise)并跨越许多 Windows VM(从 2003 到 2016 的任何版本)。

以前的 DBA 没有完成关于公司拥有的许可证数量或版本的任何文档。实际上没有有用的记录。

我已经运行MAP 工具包来收集有关 SQL Server 的详细信息。因此,至少我已经对存在哪些服务器有了一个起点,并且我已经深入研究了哪些服务器仍在提供生产数据。

我还使用了新的ApexSQL Discover工具,结果好坏参半(对不起,我喜欢你的东西,但当我需要添加 1 个服务器时,我不能等 3 天让这个工具运行)。还有dbatools find-dbainstance(不是使用 PS 导出大量数据的忠实粉丝)。因此,通过将所有这些拼凑起来,我现在相当确定我已经发现了该域中曾经存在的大部分或全部实例。

当然,我已经通过多种方式查询了许可,并彻底检查了完全无用的非常有用的 MS SQL 许可指南,其中似乎没有提供有关组织拥有的许可证或如何获取它的任何信息。

问题的症结在于:其中一些许可证是在十年(或两年)前购买的。有些肯定是纸质发票。还记得我提到过这是一个非营利组织吗?从好的方面来说,许可很便宜。另一方面,许可很便宜,因此大多数或所有许可都没有 SA,因为购买新的更便宜。编辑:这是当时不购买 SA 的原因,我没有参与。

我是否应该假设,因为很可能没有人拥有 SA——服务器也可能获得适当的许可——并根据需要购买新的?这似乎是一种可怕的方法。

我的问题:

我怎么知道我的新公司拥有哪些 SQL Server 许可证而不尝试挖掘 2004 年的纸质发票?我以前从未遇到过这种情况。是我接受审计或支付合作伙伴审计费用的唯一选择吗?(如果是这样,微软你在做什么 bb??)。

dba.se 可以在这里提供的任何见解都可能会使我的生活更上一层楼。谢谢大家!

sql-server license

11
推荐指数
1
解决办法
1517
查看次数

为什么 DELETE 查询以一种格式运行的时间比另一种格式长得多?

我有特定的清理代码试图删除一些重复项。

这在许多客户站点上完美运行。日志告诉我此查询至少消耗了 1 秒到 45 秒:

DELETE FROM [tbl]
WHERE [Id] NOT IN
(
    SELECT MIN([Id])
    FROM [tbl]
    GROUP BY [IdProject], [IdRepresentative], [TimeStart]
) 
Run Code Online (Sandbox Code Playgroud)

但是我有一个客户,该查询运行了 4 个多小时(到现在为止还没有结束)!我检查了数据库 ( DBCC CHECKDB),我已经更新了统计信息 ( sp_updatestats),也UPDATE STATISTICS [tbl] WITH FULLSCAN显示没有变化。

我有来自客户的 DB 的原始备份。我在 SQL Server 14.0.2002.14 上运行它。我有标准版,客户用的是速成版。

我可以在活动监视器中看到没有其他人在使用数据库。没有等待,CPU 使用率为 25%(正好是我的 4 个 CPU 中的 1 个)。同样在我的测试用例中,没有其他人在使用数据库。

我重新查询并检查了以下语句:

DELETE FROM [tbl]
FROM [tbl] AS t
LEFT OUTER JOIN 
    (
        SELECT MIN([Id]) AS [IdMin]
        FROM [tbl]
        GROUP BY [IdProject], [IdRepresentative], [TimeStart]
    ) …
Run Code Online (Sandbox Code Playgroud)

performance sql-server execution-plan cardinality-estimates sql-server-2017 query-performance

11
推荐指数
1
解决办法
1804
查看次数

什么是 SQL 的“不可提及的词”?

什么是 SQL 的“不可提及的词”?

我正在阅读sys.query_store_query_text (Transact-SQL)并且我看到以下内容,所以我谷歌了 {SQL "unmentionable" word}

has_restricted_text
bit
查询文本包含密码或其他不可提及的词。

除了 3 个将我带回到我找到它的位置的链接之外,我没有找到任何似乎显示与密码或 SQL 可能关心的任何关系的内容。

sql-server query-store

11
推荐指数
1
解决办法
149
查看次数

浮点数的非确定性总和

让我说出显而易见的拳头:我完全理解浮点类型不能准确表示十进制值。这不是关于那个!尽管如此,浮点计算应该是确定性的。

既然这已经解决了,让我向您展示我今天观察到的奇怪案例。我有一个浮点值列表,我想总结一下:

CREATE TABLE #someFloats (val float);
INSERT INTO #someFloats (val) VALUES (1), (1), (1.2), (1.2), (1.2), (3), (5);

SELECT STR(SUM(#someFloats.val), 30, 15) FROM #someFloats;

DROP TABLE #someFloats;

-- yields:
--   13.600000000000001
Run Code Online (Sandbox Code Playgroud)

到目前为止,一切都很好 - 这里没有惊喜。我们都知道1.2不能用二进制表示来精确表示,所以“不精确”的结果是意料之中的。

现在,当我左加入另一个表时,会发生以下奇怪的事情:

CREATE TABLE #A (a int);
INSERT INTO #A (a) VALUES (1), (2);

CREATE TABLE #someFloats (val float);
INSERT INTO #someFloats (val) VALUES (1), (1), (1.2), (1.2), (1.2), (3), (5);

SELECT #A.a, STR(SUM(#someFloats.val), 30, 15)
  FROM #someFloats LEFT JOIN …
Run Code Online (Sandbox Code Playgroud)

sql-server floating-point

11
推荐指数
1
解决办法
846
查看次数

为 SQL Server 中的所有连接设置 ARITHABORT ON 的后果是什么?

所以我确定我的 SQL Server 的不稳定行为是因为 .Net SqlClient 数据提供程序的默认设置SET ARITHABORT OFF. 话虽如此,我已经阅读了各种文章,这些文章讨论了实现这一点的最佳方式。对我来说,我只是想要一个简单的方法,因为 SQL Server 正在遭受痛苦,而且我的查询调优还没有完全超越整个应用程序(显然SET在 sp 中添加是行不通的)。

在 Erland Sommarskog关于该主题的精彩文章中,他基本上建议采取安全的方法,通过更改应用程序来发出SET ARITHABORT ON连接。但是,在 dba.stackexchange question 的这个答案中,Solomon Rutzky提供了实例范围和数据库范围的方法。

设置此实例范围内我在这里遗漏了什么后果?正如我所看到的......因为SSMSON默认设置了这个,我认为ON为所有连接设置这个服务器范围没有坏处。归根结底,我只需要这个 SQL Server 来执行高于一切。

performance sql-server ado.net execution-plan configuration

11
推荐指数
1
解决办法
1301
查看次数