小编SEa*_*986的帖子

SQL Server 如何估计嵌套循环索引查找的基数

我试图了解 SQL Server 如何估计下面的 Stack Overflow 数据库查询的基数

首先,我创建索引

CREATE INDEX IX_PostId ON dbo.Comments
(
    PostId
)
INCLUDE
(
    [Text]
)
Run Code Online (Sandbox Code Playgroud)

这是查询:

SELECT  u.DisplayName,
        c.PostId,
        c.Text
FROM    Users u
        JOIN Comments c
            ON u.Reputation = c.PostId
WHERE   u.AccountId = 22547
Run Code Online (Sandbox Code Playgroud)

执行计划在这里

首先,SQL Server 扫描用户表上的聚集索引以返回与 AccountId 谓词匹配的用户。我可以看到它使用了这个统计数据:_WA_Sys_0000000E_09DE7BCC

在此输入图像描述

我可以看到该用户没有范围高键,因此 SQL Server 使用 avg_range 行并估计 1

在此输入图像描述

评论索引搜索的搜索谓词是

在此输入图像描述

soScalar Operator([StackOverflow2010].[dbo].[Users].[Reputation] as [u].[Reputation]表示users表中accountId为的用户的信誉值22547

我可以看到总共加载了三个统计数据:

_WA_Sys_0000000E_09DE7BCC- Users.AccountId(用于估计聚集索引查找谓词)

IX_PostId- Comments.PostId(用于估计索引查找谓词)

_WA_Sys_0000000A_09DE7BCC- 用户.声誉 (?)

SQL Server 如何得出索引查找的估计值?它无法在编译时知道 accountId 的信誉,22547因为帐户 …

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

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

缓慢的并行 SQL Server 查询,串行几乎是即时的

我有一个 SQL Server 查询如下(混淆):

UPDATE  [TABLE1]
SET     [COLUMN1] = CAST('N' AS CHAR(1))
FROM    [TABLE1]
WHERE   (COLUMN1 = '2' AND COLUMN2 IN('VAL1', 'VAL2', 'VAL3')) OR 
        (COLUMN1 <> 'N' AND (
                                    SELECT  COUNT(*)
                                    FROM    TABLE2 wle
                                            JOIN TABLE3 wl 
                                                    ON wl.COLUMN3 = wle.COLUMN3
                                    WHERE   TABLE1.COLUMN4 = wle.COLUMN4 AND 
                                            (wl.COLUMN5 = '1' OR wl.COLUMN6 = '1') AND 
                                            wle.COLUMN7 = (
                                                            SELECT  MIN(alias.COLUMN7)
                                                            FROM    TABLE2 AS alias
                                                            WHERE   TABLE1.COLUMN4 = alias.COLUMN4
                                                            )
                                ) > 0
                                            
        )
Run Code Online (Sandbox Code Playgroud)

我们刚刚将我们的(测试)服务器从 SQL Server 2014 SP3 升级到 SQL Server …

parallelism sql-server-2016 query-performance

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

为什么 Varchar 的数据类型优先级低于 INT?

给出下表:

CREATE TABLE #a
(
    MyInt INT
)

INSERT INTO #a VALUES(1),(2),(3),(4),(5),(6),(7),(8),(9),(10)

CREATE TABLE #b
(
    MyVarchar VARCHAR(10)
)

INSERT INTO #b VALUES('1'),('2'),('3'),('4'),('5'),('6'),('7'),('8'),('9'),('ten')
Run Code Online (Sandbox Code Playgroud)

如果我运行以下查询;

SELECT  *
FROM    #a
        LEFT JOIN #b
            ON #a.MyInt = #b.MyVarchar
Run Code Online (Sandbox Code Playgroud)

SQL Server 必须执行隐式转换,因为#a.MyInt#b.MyVarchar是不匹配的数据类型。由于数据类型优先级,具有最低类型优先级 (#b.MyVarchar) 的列将转换为较高优先级 (INT) 的类型

这意味着上面的查询等效于

SELECT  *
FROM    #a
        LEFT JOIN #b
            ON #a.MyInt = CONVERT(INT,#b.MyVarchar)
Run Code Online (Sandbox Code Playgroud)

两者都失败,因为其中某个值#b.MyVarchar对于列来说是无效值INT

我的问题是为什么 的VARCHAR优先级低于INT?如果是相反的情况,隐式转换将会成功,但我们会得到一个错误的查询。为什么错误比成功执行更可取?我的猜测是,这对于 SQL Server 来说更像是一种“防御”机制 - 它更喜欢错误,因此需要用户明确决定他们想要做什么,而不是在用户不知情的情况下给出可能意外的查询结果。意识到?

sql-server datatypes errors implicit-conversions

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

错误严重性 16 针对 is_event_logged = 0 的事件发出警报

我的错误级别 16 警报设置如下:

USE [msdb]
GO

EXEC msdb.dbo.sp_add_alert @name=N'Error - Severity 16', 
        @message_id=0, 
        @severity=16, 
        @enabled=1, 
        @delay_between_responses=0, 
        @include_event_description_in=1, 
        @category_name=N'[Uncategorized]', 
        @job_id=N'00000000-0000-0000-0000-000000000000'
Run Code Online (Sandbox Code Playgroud)

我很好奇为什么

SELECT 1/0;
Run Code Online (Sandbox Code Playgroud)

消息 8134,级别 16,状态 1,第 17 行 遇到除零错误。

没有引发错误,但是

BACKUP DATABASE MyDatabase TO DISK = 'C:\FolderThatDoesntexist'
Run Code Online (Sandbox Code Playgroud)

消息 3201,级别 16,状态 1,第 8 行 无法打开备份设备“C:\FolderThatDoesntexist”。操作系统错误 5(访问被拒绝。)。

消息 3013,级别 16,状态 1,第 8 行备份数据库异常终止。

曾是

这篇文章它引用的博客文章表明 SQL Server 只会针对记录的错误引发事件,这可以在sys.messages

所以我查询sys.messages了这些错误代码:

SELECT  severity,
        message_id,
        is_event_logged
FROM    sys.messages
WHERE   language_id = 1033 AND
        message_id IN (8134,3201,3013)
Run Code Online (Sandbox Code Playgroud)

但发现这三个都设置为0:

在此输入图像描述

为什么 3201 …

errors alerts raiserror sql-server-2016

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

缓冲池到底有多重要?

我一直在对新的(虚拟)服务器进行一些测试,以替换现有的生产服务器。我们怀疑当前的生产服务器规格过高,因此正在从低水平调整新服务器的虚拟组件(RAM、CPU 等),直到性能适合处理当前的工作负载。

虽然认识到新服务器处理现有服务器工作负载的能力的真正测试是针对新服务器测试该工作负载,但出于兴趣,我对现有服务器和新服务器进行了一些简单的、任意的测试:

  • 恢复数据库-读取速度
  • 备份数据库-写入速度
  • 大型数据库上的 DBCC CHECKDB - 花费的时间

(两台服务器上使用相同的数据库备份,以使上述所有测试保持一致)

以上所有内容都支持新服务器(更快的读写速度、更快的 CHECKDB)

我做的最后一个基本测试是测试执行一个简单的操作所需的时间SELECT *在冷缓存和热缓存上最大的表之一上执行简单操作所需的时间,以进一步了解读取速度。

测试代码如下,我在两台服务器上运行

USE StackOverflow

SET STATISTICS IO, TIME ON

CHECKPOINT

DBCC DROPCLEANBUFFERS

SELECT * FROM Users  /* cold cache run */
SELECT * FROM Users  /* warm cache run */
Run Code Online (Sandbox Code Playgroud)

统计IO如下:

SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 12 ms.
DBCC execution completed. If DBCC printed error messages, contact your system administrator.

 SQL Server Execution Times:
   CPU time = …
Run Code Online (Sandbox Code Playgroud)

performance sql-server memory buffer-pool sql-server-2017

0
推荐指数
1
解决办法
565
查看次数