小编SEa*_*986的帖子

sp_WhoIsActive vs sp_BlitzFirst @ExpertMode = 1

我使用sp_WhoIsActivesp_BlitzFirstExpertMode参数设置为 1)来实时了解 SQL Server 上发生的情况。我觉得这是对的升级sp_whosp_who2等等......

任何人都可以解释一下,如果两者之间有任何区别。它们似乎显示相同的内容,尽管列的设置略有不同。此外,BlitzFirst 在其输出中显示了一些其他信息作为单独的输出表

这个视频中,布伦特展示了他的分类过程,他同时使用了这两种方法sp_WhoIsActivesp_BlitzFirst这让我觉得肯定有一些不同,但除非我错过了视频中的某些内容,否则我不明白为什么sp_WhoIsActive需要

sql-server troubleshooting sp-blitzfirst sp-whoisactive

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

将 VARCHAR 列隐式转换为 NVARCHAR 不会导致预期的表扫描

鉴于以下脚本,我可以看到隐式转换和数据类型优先级对查询计划有负面影响

-- create objects
CREATE DATABASE ConvertTest
GO

USE ConvertTest
GO

CREATE TABLE Person
(
    VarcharId   NVARCHAR(4),
    IntId       INT 
)

-- insert data
INSERT INTO Person
SELECT  TOP 1000
        CONVERT(NVARCHAR(4),ROW_NUMBER() OVER (ORDER BY a.object_id)),
        ROW_NUMBER() OVER (ORDER BY a.object_id)
FROM    sys.objects a
        CROSS JOIN sys.objects b

-- create indexes
CREATE INDEX IX_Varchar ON Person
(
    VarcharId,
    IntId   
)

CREATE INDEX IX_Int ON Person
(
    IntId,
    VarcharId
)

DECLARE @id NVARCHAR(4) = 100
-- statement 1
SELECT * FROM …
Run Code Online (Sandbox Code Playgroud)

performance datatypes execution-plan type-conversion sql-server-2014

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

在 sys.databases 上游标会跳过数据库

我知道这个问题已经被问过好几次了,我知道解决方案,但我试图了解问题的根本原因:

我有以下代码来执行数据库备份。

DECLARE @Filename   VARCHAR(256)
DECLARE @FileDate   VARCHAR(15) 
DECLARE @Path       VARCHAR(50) 
DECLARE @Name       VARCHAR(50) 

-- specify database backup directory
SET @Path = '\MyPath'

-- specify filename date
SELECT @FileDate = CONVERT(VARCHAR(20), GETDATE(), 112) + '_' + REPLACE(CONVERT(VARCHAR(20), GETDATE(), 108),':','')

DECLARE db_cursor CURSOR FOR
    SELECT [name]
        FROM master.sys.databases
        WHERE [name] NOT IN ('master', 'msdb', 'model', 'tempdb')
            AND [state_desc] = 'ONLINE'

OPEN db_cursor
FETCH NEXT FROM db_cursor INTO @Name

WHILE @@FETCH_STATUS = 0
BEGIN

    SET @Filename = @Path + @Name + '_Full_Backup_' …
Run Code Online (Sandbox Code Playgroud)

dmv cursors sql-server-2016

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

更改游标内的 SET 选项 - 基于兼容性级别的不同行为

我发现数据库兼容性级别之间的一段代码的行为存在差异,并想知道其原因是什么。下面是一个简单的示例,它迭代计数表并ROWCOUNT在第 50 次迭代时更改选项:

设置:

/* Create tally table */

SELECT  TOP 100
        ROW_NUMBER() OVER (ORDER BY a.object_id) AS Number
INTO    #Tally
FROM    sys.objects a
        CROSS JOIN sys.objects b;

/* Create Some databases with different compatibility levels */

CREATE DATABASE [100Compat] WITH COMPATIBILITY_LEVEL = 100
CREATE DATABASE [110Compat] WITH COMPATIBILITY_LEVEL = 110
CREATE DATABASE [120Compat] WITH COMPATIBILITY_LEVEL = 120
CREATE DATABASE [130Compat] WITH COMPATIBILITY_LEVEL = 130
Run Code Online (Sandbox Code Playgroud)

受影响的代码:

/* cursor through the tally table */
DECLARE MyCursor CURSOR
FOR
SELECT …
Run Code Online (Sandbox Code Playgroud)

sql-server-2008 cursors sql-server-2016 compatibility-level

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

默认架构允许在不使用架构前缀的情况下选择 dbo 表

我在我的服务器上创建了一个登录名和一个数据库用户,如下所示:

USE master
GO
CREATE LOGIN MyLogin WITH PASSWORD=N'Password123!'
GO
USE AdventureWorks2014
GO
CREATE USER MyLogin FOR LOGIN MyLogin
GO
ALTER USER MyLogin WITH DEFAULT_SCHEMA=HumanResources
GO
GRANT SELECT ON SCHEMA :: Production TO MyLogin
GO
GRANT SELECT ON SCHEMA :: HumanResources TO MyLogin
GO
GRANT SELECT ON SCHEMA :: dbo TO MyLogin
Run Code Online (Sandbox Code Playgroud)

当我作为 MyLogin 登录时,我现在可以在 HumanResources 模式中选择对象而不使用四部分名称(因为 HumanResources 是该用户的默认模式)

SELECT * FROM HumanResources.Department
Run Code Online (Sandbox Code Playgroud)

现在可以在没有架构名称的情况下运行:

SELECT * FROM Department
Run Code Online (Sandbox Code Playgroud)

这可以。如果我然后尝试从生产模式中的表中选择而不使用模式前缀:

SELECT * FROM ProductDescription
Run Code Online (Sandbox Code Playgroud)

我按预期收到错误。这可以通过使用以下方法解决:

SELECT * FROM Production.ProductDescription
Run Code Online (Sandbox Code Playgroud)

因此,基于此,我需要在从默认架构之外的任何表中进行选择时指定架构名称。

那么为什么当我从 …

schema sql-server permissions sql-server-2014

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

如何确定创建索引的成本?

我有一个表,我想在其上创建索引以提高SELECT使用该表的几个查询的性能。

如何测试索引是否对表上的 DUI 操作产生了任何显着的不利影响?

该表是日志表,因此经常写入。在创建所需索引之前和之后针对该表运行特定INSERTUPDATE查询是一种情况吗?

performance index sql-server sql-server-2014

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

对执行缓慢的加密存储过程进行故障排除

我有一个存储过程,它是供应商提供的系统的一部分。存储过程是加密的,所以我们看不到代码。

存储过程突然开始运行缓慢。

我想看看做的第一件事是看执行计划,试图找出是,然而,似乎问题出在哪里不是要显示该计划的方式(sp_Whoisactive就是NULL在query_plan场)

我也可能会尝试更新统计信息,但我无法查看存储过程使用的表。

查询的等待统计信息没有显示任何明显的信息

在没有未加密版本的情况下,是否真的可以对此查询进行任何类型的故障排除?

sql-server stored-procedures encryption troubleshooting sql-server-2014

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

Index Seek 根据参数值扫描整个表

我有一个疑问:

SELECT  Id, 
        ColumnA,
        ColumnB
FROM    MyTable
WHERE   ColumnA = @varA OR
        ColumnB = @varB  
Run Code Online (Sandbox Code Playgroud)

该表定义为

CREATE TABLE MyTable
(
    Id INT IDENTITY(-2147483648,1) PRIMARY KEY,
    ColumnA VARCHAR(22)
    ColumnB VARCAHR(22)
)
Run Code Online (Sandbox Code Playgroud)

并且表上有一个非聚集索引

CREATE INDEX IX_MyIndex ON MyTable
(
    ColumnA
)
Run Code Online (Sandbox Code Playgroud)

当我使用以下参数运行查询时:

DECLARE @varA nvarchar(4000) = ''
DECLARE @varB  nvarchar(8) = '10140730'
Run Code Online (Sandbox Code Playgroud)

执行计划显示索引搜索IX_MyIndex,但它显示读取的行数为 1700 万行,但实际行数为 0(MyTable.ColumnA 中有 0 行,值为 '')如果我转动,SET STATISTICS IO ON我可以看到完整的表正在阅读

这是有道理的:“这是一个“糟糕的”索引搜索部分中的这篇文章

但是,当我使用参数运行相同的查询时:

DECLARE @varA nvarchar(8) = 'a'
DECLARE @varB  nvarchar(8) = '10140730'
Run Code Online (Sandbox Code Playgroud)

搜索运算符没有“读取的行数”属性(MyTable.ColumnA 中有 …

performance sql-server execution-plan type-conversion query-performance

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

嵌套循环运算符使用什么方法/公式进行行估计?

AdventureWorks 中的以下简单查询:

SELECT  *
FROM    Person.Person p
        JOIN HumanResources.Employee e
            ON p.BusinessEntityID = e.BusinessEntityID
Run Code Online (Sandbox Code Playgroud)

给出以下执行计划:

新的估算器计划

如果我查看上面的计划,我可以看到索引扫描和索引搜索都(正确)估计了 290 行,但是,连接两者的估计循环运算符估计了 279 行。

旧估算器

旧的估计器也正确地猜测了搜索和扫描中的 290 行,但嵌套循环估计了 289 行,在这个查询的情况下这是一个更好的估计。

那么在新 CE 的情况下,优化器估计当它连接索引扫描中的 290 行和索引查找中的 290 行时,是否会有 11 行不匹配?

它使用什么方法/公式来进行这个估计?

我所说的任何方法都是正确的,它已经从早期的 CE 版本改变了,因为它做出了不同的估计?

我意识到新 CE 的“坏”估计不足以损害性能,我只是想了解估计器处理

sql-server sql-server-2016 cardinality-estimates

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

查询存储计划不强制并且没有失败原因

我在查询存储中强制执行了一个计划,如下所示

EXEC sys.sp_query_store_force_plan @query_id = 113366, @plan_id = 3687662

但是当我再次运行查询时,查询不使用该计划,也不显示failure_force_reason

以下查询显示该计划已被强制,并表明上次运行时强制没有失败

SELECT  plan_id,
        query_id,
        is_forced_plan,
        last_force_failure_reason_desc
FROM    sys.query_store_plan
WHERE   is_forced_plan = 1
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

以下查询显示了相关查询的最后一次运行时间,这向我证实,我确实重新运行了这个查询,并且它使用了与我强制执行的计划不同的计划:

SELECT  TOP 1
        q.query_id,
        p.plan_id,
        s.last_execution_time,
        SYSDATETIMEOFFSET() AS CurrentTime
FROM    sys.query_store_query q
        JOIN sys.query_store_plan p
            ON q.query_id = p.query_id
        JOIN sys.query_store_runtime_stats s
            ON s.plan_id = p.plan_id
WHERE   q.query_id = 113366
ORDER BY s.last_execution_time DESC
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

为什么查询存储似乎忽略了这个计划的力量?我可以利用任何扩展事件或其他故障排除工具来了解吗?

sql-server execution-plan query-store sql-server-2019

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