标签: execution-plan

无法执行查询,甚至无法生成估计执行计划

我正在研究SQL Server 2019

我有一个表dbo.AllDates其中包含从19902050的所有日期。我有另一个表dbo.ActualExchangeRates,其中我有在给定来源中找到汇率的日期某些货币的实际汇率。

我正在尝试编写一个查询来获取2010 年2020 年之间所有日期的所有货币。如果找到比率,则写入比率,否则写入NULL

鉴于这种情况和下面给出的代码,有人可以帮助我理解为什么SELECT查询没有生成任何结果,甚至无法看到估计的执行计划吗?

CREATE TABLE dbo.AllDates(Date date)
CREATE TABLE dbo.ActualExchangeRates(Date date, Currency char(3), Rate real)

--Query 1: Not generating any results or estimated plan
SELECT      d.Date, m.Currency, c.Rate
FROM        dbo.AllDates d
INNER JOIN  (
    select
      currency,
      '20100101' as mindate,
      '20201231' as maxdate
    from dbo.ActualExchangeRates
    group by currency
) as m on d.date between m.mindate and m.maxdate
LEFT …
Run Code Online (Sandbox Code Playgroud)

sql-server execution-plan sql-server-2019 query-performance

12
推荐指数
2
解决办法
928
查看次数

使用函数调用的估计与实际查询计划

我在 SQL 服务器上有这个查询,一个合并复制查询:

SELECT DISTINCT
    b.tablenick,
    b.rowguid,
    c.generation,
    sys.fn_MSgeneration_downloadonly
    (
        c.generation,
        c.tablenick
    )
FROM #belong b
LEFT OUTER JOIN dbo.MSmerge_contents c ON 
    c.tablenick = b.tablenick
    AND c.rowguid = b.rowguid;
Run Code Online (Sandbox Code Playgroud)

估计的查询计划包括 3 个查询的信息:

  1. 上面的查询
  2. 对 fn_MSgeneration_downloadonly 的函数调用
  3. fn_MSArticle_has_downloadonly_property 的函数调用

实际的查询计划仅包括以下信息:

  1. 上面的查询

没有关于功能。为什么实际方案中缺少功能信息?

我尝试了这些选项:

SET STATISTICS PROFILE ON
SET STATISTICS XML ON
Run Code Online (Sandbox Code Playgroud)

它创建了一个实际计划,但它缺少第 2 部分和第 3 部分,这与我在 Management Studio 中使用实际查询计划选项时相同。

例如,如果我要使用 Profiler 来捕获有关函数调用的信息,我会选择哪些事件?


没有找到与查询计划特别相关的答案,但我分析了 SP:StmtStarting 和 SP:StmtCompleted 并显示了函数调用。

sql-server execution-plan functions merge-replication

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

SQL Server 是如何生成加起来达到 6,000% 的查询执行计划的?

奇怪的执行计划

今天我在 The Heap 上,正在查看我认为可以改进的查询计划。然而,它创造了一些东西,动摇了我对 SQL Server 查询优化器的信念。如果甚至不能计数到 100%,我还可以信任它吗?

表的特点:

  • 聚集在非标识列上
  • 12 个索引,其中之一是相关date_entered
  • 60,000 条记录
  • 26列不同类型和长度
  • PAGE 压缩表

有没有人以前见过这个,是什么导致计划看起来如此扭曲?


以下来自 SQL Sentry Plan Explorer

SQL Sentry 计划资源管理器 - 图像 顶级运营

sql-server optimization ssms execution-plan sql-server-2012

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

SQL Server 查询计划 XML:QueryPlanHash 长度

更新:这绝对是一个错误。有关完整详细信息,请参阅此连接项

在测试sp_BlitzCache 的一些更改(完全公开,我是作者之一)时,我发现了我认为是我们代码中的错误。

在某一时刻,我们匹配查询计划哈希以获得查询成本。我们这样做:

statement.value('sum(/p:StmtSimple[xs:hexBinary(substring(@QueryHash, 3)) =
    xs:hexBinary(sql:column("b.QueryHash"))]/@StatementSubTreeCost)', 'float')
Run Code Online (Sandbox Code Playgroud)

就我所见,这已经奏效了。然而,在一个奇怪的情况下,XML 中的子字符串抛出一个NULL值,并且计划显示成本为 0,尽管它相当高。

深入研究执行计划(完全公开,我为托管 Paste The Plan 的公司工作),我注意到一个问题哈希的查询计划哈希长度为 17 个字符,而其余为 18 个字符。以下是示例:

QueryPlanHash="0x4410B0CA640CDA89"
QueryPlanHash="0x2262FEA4CE645569" 
QueryPlanHash="0xED4F225CC0E97E5" -- 问题!
QueryPlanHash="0xBF878EEE6DB955EA"
QueryPlanHash="0x263B53BC8C14A452"
QueryPlanHash="0x89F5F146CF4B476F"
QueryPlanHash="0xEF47EA40805C8961"
QueryPlanHash="0xB7BE27D6E43677A5"
QueryPlanHash="0x815C54EC43A6A6E9"

查询计划哈希上市BINARY 8-想必这应该是相同的长度,但到底是什么像我这样的人了解二进制值?

稍微使用 XQuery,我发现通过将子字符串更改为从第二个位置开始,它会得出一个有效(尽管不正确)的哈希值。

WITH XMLNAMESPACES('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS p)
SELECT   
        QueryPlanCost = statement.value('sum(/p:StmtSimple/@StatementSubTreeCost)', 'float'),
        **q.n.value('substring(@QueryPlanHash, 2)', 'BINARY(8)')**
FROM    #statements s
CROSS APPLY s.statement.nodes('/p:StmtSimple') AS q(n)
OPTION(RECOMPILE);

WITH XMLNAMESPACES('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS p)
SELECT   
        QueryPlanCost = statement.value('sum(/p:StmtSimple/@StatementSubTreeCost)', 'float'),
        **q.n.value('substring(@QueryPlanHash, …
Run Code Online (Sandbox Code Playgroud)

xml sql-server datatypes execution-plan

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

在 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
查看次数

为什么 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 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
查看次数

当构建端为空时,SQL Server 为什么/何时评估内部散列连接的探测端?

设置

DROP TABLE IF EXISTS #EmptyTable, #BigTable

CREATE TABLE #EmptyTable(A int);
CREATE TABLE #BigTable(A int);

INSERT INTO #BigTable
SELECT TOP 10000000 CRYPT_GEN_RANDOM(3)
FROM   sys.all_objects o1,
       sys.all_objects o2,
       sys.all_objects o3;
Run Code Online (Sandbox Code Playgroud)

询问

WITH agg
     AS (SELECT DISTINCT a
         FROM   #BigTable)
SELECT *
FROM   #EmptyTable E
       INNER HASH JOIN agg B
                    ON B.A = E.A;
Run Code Online (Sandbox Code Playgroud)

执行计划

在此处输入图片说明

问题

这是我今天之前没有注意到的现象的简化再现。我对内部散列连接的期望是,如果构建输入为空,则不应执行探测端,因为连接不会返回任何行。上面的示例与此相反,并从表中读取了 1000 万行。这使查询的执行时间增加了 2.196 秒 (99.9%)。

其他观察

  1. 使用OPTION (MAXDOP 1)执行计划从#BigTable. 该ActualExecutions0对哈希连接内所有的运营商。
  2. 对于查询SELECT * FROM #EmptyTable E INNER …

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

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

为什么 SQL Server 能够准确跟踪某些多语句表值函数查询计划的时间,而其他查询计划则不然?

设置

在本演示中,我使用的是2013 版 Stack Overflow 数据库和 SQL Server 2022 CTP2,但回溯到 SQL Server 2017 也是有效的,这是我想检查的最早版本。

功能一

对于此函数,SQL Server 跟踪该函数所花费的执行时间:

CREATE OR ALTER FUNCTION
    dbo.ScoreStats
(
    @UserId int
)
RETURNS
    @out table
    (
        TotalScore bigint
    )
WITH SCHEMABINDING
AS 
BEGIN

    INSERT
        @out
    (
        TotalScore
    )
    SELECT
        TotalScore = 
            SUM(x.Score)
    FROM 
    (
        SELECT
            Score = 
                SUM(p.Score)
        FROM dbo.Posts AS p
        WHERE p.OwnerUserId = @UserId

        UNION ALL

        SELECT
            Score = 
                SUM(c.Score)
        FROM dbo.Comments AS c
        WHERE c.UserId = @UserId    
    ) AS x; …
Run Code Online (Sandbox Code Playgroud)

sql-server execution-plan functions

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