标签: execution-plan

为什么计算执行计划需要这么长时间?

我们的一位客户刚刚升级到新服务器。

对于一个特定的存储过程,第一次执行它需要三分钟的时间来运行。后续运行不到 1 秒。

这让我相信最初的三分钟主要用于计算执行计划。后续运行只需使用缓存的计划并立即运行。

在我们的测试数据库上,计算相同程序的计划大约需要 5 秒。

我在计划本身中没有看到任何可怕的东西 - 尽管我不认为它是相关的,因为计划显示了运行查询需要多长时间,而不是计算本身。

该服务器为 16 核,24 GB 内存。不会发生沉重的 CPU 或内存负载。

是什么导致仅在特定数据库上计算如此缓慢?

我可以采取哪些步骤来找出问题的原因?

编辑

所以我设法访问服务器并使用SET SHOWPLAN_XML ON运行查询。

我可以确认查询的 CompileTime 占用了查询执行时间的 99%。该StatementOptmEarlyAbortReason“超时”,我们与他们的数据库副本的原因是MemoryLimitExceeded测试数据库。

sql-server-2008 sql-server execution-plan

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

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

没有 PARTITION BY 的 ROW_NUMBER() 仍然生成 Segment 迭代器

我正在撰写我即将发表的关于排名和聚合窗口函数的博客文章,特别是 Segment 和 Sequence Project 迭代器。我理解的方式是 Segment 标识流中构成组结束/开始的行,因此以下查询:

SELECT ROW_NUMBER() OVER (PARTITION BY someGroup ORDER BY someOrder)
Run Code Online (Sandbox Code Playgroud)

将使用 Segment 来判断一行何时属于前一行以外的不同组。然后 Sequence Project 迭代器根据 Segment 迭代器的输出进行实际的行号计算。

但是使用该逻辑的以下查询不应包含 Segment,因为没有分区表达式。

SELECT ROW_NUMBER() OVER (ORDER BY someGroup, someOrder)
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试这个假设时,这两个查询都使用了 Segment 运算符。唯一的区别是第二个查询不需要GroupBy在 Segment 上。这不是首先消除了对 Segment 的需求吗?

例子

CREATE TABLE dbo.someTable (
    someGroup   int NOT NULL,
    someOrder   int NOT NULL,
    someValue   numeric(8, 2) NOT NULL,
    PRIMARY KEY CLUSTERED (someGroup, someOrder)
);

--- Query 1:
SELECT ROW_NUMBER() OVER (PARTITION BY someGroup ORDER BY someOrder)
FROM …
Run Code Online (Sandbox Code Playgroud)

sql-server execution-plan

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

了解统计数据、执行计划和“上升的关键问题”

我试图更好地理解(从概念上)统计、执行计划、存储过程执行之间的关系。

我说统计信息仅在为存储过程创建执行计划时使用,而在实际执行上下文中不使用,我说的对吗?换句话说,如果这是真的,一旦创建了计划(并假设它被正确重用),“最新”统计数据有多重要?

我读过的一篇文章(统计、行估计和升序日期列)特别激励我,该文章描述的场景与我每天面对的几个客户数据库非常相似。

在我们使用特定存储过程定期查询的最大表之一中,我们有一个升序日期/时间列。

当您每天添加十万行时,您如何防止执行计划变得陈旧?

如果我们经常更新统计信息来解决这个问题,在这个存储过程的查询中使用 OPTION (RECOMPILE) 提示是否有意义?

任何意见或建议将不胜感激。

更新:我使用的是 SQL Server 2012 (SP1)。

sql-server statistics execution-plan sql-server-2012

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

将查询计划按语句拆分以实现可重用性会更好吗?

根据我对查询如何编译、存储和检索查询计划的有限了解,我了解多语句查询或存储过程将生成它的查询计划,该查询计划将存储在查询计划缓存中,以供查询在未来执行中使用。

我认为这个计划是通过查询哈希从查询计划缓存中检索的,这意味着如果查询被编辑和执行,哈希是不同的,并且会生成一个新计划,因为在查询计划缓存中找不到匹配的哈希。

我的问题是:如果用户执行的语句是多语句查询中的语句之一,它是否可以将缓存中已有的查询计划的相关部分用于多语句查询?我希望答案是否定的,因为哈希值显然不匹配,但是在多语句查询中对每个语句进行哈希处理是否更好,以便用户可以从查询中运行单个语句来使用它们?

我希望有一些我没有考虑到的并发症(我真的很想知道这些),但似乎我们可以在许多查询计划中存储相同的“语句计划”,占用更多空间和更多CPU 和生成时间。

可能只是显示我的无知。

sql-server execution-plan plan-cache

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

如何回答为什么突然需要更改索引或查询

我是初级 DBA,有 3 年的经验。我们的工作是微调查询或建议开发人员应该重写特定代码或需要索引。

开发团队经常问的一个简单问题是:“昨天运行良好,突然发生了什么变化?” 我们将被要求检查基础设施方面。对任何问题的第一反应似乎总是将最大的责任归咎于基础设施,这始终是首先要验证的事情。

我们应该如何回答开发团队提出的“改变了什么”的问题?大家有遇到过同样的情况吗?如果是这样,请分享您的经验。

performance sql-server execution-plan

11
推荐指数
3
解决办法
879
查看次数

Sql Server 无法在简单双射上使用索引

这是另一个查询优化器难题。

也许我只是高估了查询优化器,或者我遗漏了一些东西 - 所以我把它放在那里。

我有一张简单的桌子

CREATE TABLE [dbo].[MyEntities](
  [Id] [uniqueidentifier] NOT NULL,
  [Number] [int] NOT NULL,
  CONSTRAINT [PK_dbo.MyEntities] PRIMARY KEY CLUSTERED ([Id])
)

CREATE NONCLUSTERED INDEX [IX_Number] ON [dbo].[MyEntities] ([Number])
Run Code Online (Sandbox Code Playgroud)

有一个索引和几千行,Number均匀分布在值 0、1 和 2 中。

现在这个查询:

SELECT * FROM
    (SELECT
        [Extent1].[Number] AS [Number],
        CASE
        WHEN (0 = [Extent1].[Number]) THEN 'one'
        WHEN (1 = [Extent1].[Number]) THEN 'two'
        WHEN (2 = [Extent1].[Number]) THEN 'three'
        ELSE '?'
        END AS [Name]
        FROM [dbo].[MyEntities] AS [Extent1]
        ) P
WHERE P.Number = 0;
Run Code Online (Sandbox Code Playgroud)

是否 …

sql-server execution-plan sql-server-2016

11
推荐指数
3
解决办法
776
查看次数

索引搜索操作员成本

对于下面的AdventureWorks示例数据库查询:

SELECT 
    P.ProductID, 
    CA.TransactionID
FROM Production.Product AS P
CROSS APPLY
(
    SELECT TOP (1)
        TH.TransactionID
    FROM Production.TransactionHistory AS TH
    WHERE
        TH.ProductID = P.ProductID
    ORDER BY 
        TH.TransactionID DESC
) AS CA;
Run Code Online (Sandbox Code Playgroud)

执行计划显示索引搜索估计操作员成本0.0850383 (93%) :

计划

成本与使用的基数估计模型无关。

它不是简单地将Estimated CPU CostEstimated I/O Cost相加。它也不是指数搜索的一次执行成本乘以估计执行次数

这个成本数字是如何得出的?

sql-server execution-plan database-internals

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

为什么不使用 sys.query_store_plan 加入消除工作?

以下是查询存储遇到的性能问题的简化:

CREATE TABLE #tears
(
    plan_id bigint NOT NULL
);

INSERT #tears (plan_id) 
VALUES (1);

SELECT
    T.plan_id
FROM #tears AS T
LEFT JOIN sys.query_store_plan AS QSP
    ON QSP.plan_id = T.plan_id;
Run Code Online (Sandbox Code Playgroud)

plan_id列被记录为 的主键sys.query_store_plan,但执行计划并不像预期的那样使用连接消除

  1. DMV 没有投射任何属性。
  2. DMV 主键plan_id不能复制临时表中的行
  3. 使用了 A LEFT JOIN,因此无法T消除from中的任何行。

执行计划

平面图

为什么会这样,在这里可以做些什么来消除连接?

performance join sql-server execution-plan query-store query-performance

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

哈希聚合救助

在聊天讨论中出现的一个问题:

我知道散列连接救助在内部切换到某种嵌套循环。

SQL Server 为散列聚合救助做了什么(如果它可以发生的话)?

sql-server aggregate execution-plan database-internals hashing

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