标签: execution-plan

SQL Server,TOP 与 ROW_NUMBER

我正在学习执行计划并尝试不同的查询并比较它们的性能并偶然发现了这一点:

SELECT StatisticID
FROM (
    SELECT StatisticID, ROW_NUMBER() OVER (ORDER BY StatisticID) AS rn
    FROM FTCatalog.Statistic
    ) AS T
WHERE T.rn <= 1000
ORDER BY rn

SELECT TOP 1000 StatisticID
FROM FTCatalog.Statistic
ORDER BY StatisticID
Run Code Online (Sandbox Code Playgroud)

它们都返回相同的结果集 - 但是第一个执行速度更快并且资源消耗更少(至少 SSMS 告诉我)这是执行计划: 执行计划

与 SQL 查询计划资源管理器的比较: 在此处输入图片说明 谁能给我一些关于幕后实际发生的事情以及结果为何不同的见解?如果您还有什么需要 - 请告诉我。

谢谢,埃瓦尔达斯。

performance sql-server execution-plan query-performance

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

sp_WhoIsActive (SQL Server 2008 R2) 上有很多“FETCH API_CURSOR0000...”

我有一个奇怪的情况。使用sp_whoisactive我可以看到:

奇怪的

好的,通过这个查询,我可以看到是什么触发了(这个词在英语中存在吗?)它:

SELECT c.session_id, c.properties, c.creation_time, c.is_open, t.text
FROM sys.dm_exec_cursors (SPID) c --0 for all cursors running
CROSS APPLY sys.dm_exec_sql_text (c.sql_handle) t
Run Code Online (Sandbox Code Playgroud)

结果:

它只是一个选择

这是一个简单的select. 为什么要使用 f etch_cursor

另外,我也看到了很多“空白”的 sql_texts。这与这个“光标”有关系吗?

空白的

DBCC INPUTBUFFER (spid) 给我看这个:

打印

有这个问题 在这里(我做的),但我不知道这是否是同样的事情。


编辑1:

使用 kin 提供的查询,我看到了这一点:

仍然没有代码。


编辑2:

使用活动监视器,我可以看到:

最昂贵的查询

这是最昂贵的查询(第一个是故意的,我们知道)。

再一次,我想知道,为什么这select * from...FETCH CURSOR……的原因。


编辑3:

这个“ select * from...”是从另一台服务器(通过linked server)运行的。

好吧,现在我无法理解@kin 所说的内容。

这是execution plan查询的(在数据库的同一服务器中运行):

数据库的同一台服务器

这是现在,通过链接服务器在另一台服务器上运行的执行计划:

在此处输入图片说明

好的,也不是问题。现在!执行计划,通过**activity monitor**(相同select * from):

这到底是怎么回事?

sql-server-2008 process execution-plan cursors

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

估计操作员成本计算

我读过的任何地方都说估计操作员成本是估计 CPU 成本和估计 I/O 成本的总和。但是,在我看到的许多运营商中,情况并非如此。下面是一个例子:

SELECT Column2
INTO   Object1
FROM   Object2
WHERE  Column3 >= Variable2
       AND Column3 <= Variable1
       AND ( Column4 = Variable5
              OR Variable5 = ? ) 
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

EstimateIO="0.01" EstimateCPU="0.000246492"

总和:0.010246492

然而,SSMS 将此 0.073823 显示为估计的运营商成本。我完全不知道这是如何计算的。下面是执行计划 xml(匿名)。Node Id 0 是有问题的节点。

<?xml version="1.0" encoding="utf-16"?>
<ShowPlanXML xmlns="http://schemas.microsoft.com/sqlserver/2004/07/showplan" Version="1.2" Build="11.0.6537.0">
    <BatchSequence>
        <Batch>
            <Statements>
                <StmtSimple StatementText="&#x9;SELECT Column2 INTO Object1 &#xD;&#xA;&#x9;FROM Object2&#xD;&#xA;&#x9;WHERE Column3&gt;=Variable2 AND Column3&lt;=Variable1 &#xD;&#xA;&#x9;AND (Column4=Variable5 OR Variable5=?)&#xD;&#xA;&#xD;&#xA;" StatementId="1" StatementCompId="7" StatementType="SELECT INTO" RetrievedFromCache="true" StatementSubTreeCost="0.405134" StatementEstRows="246.492" StatementOptmLevel="FULL" QueryHash="0x180DF38DFFFEAFA2" QueryPlanHash="0x45A4295471B90968" StatementOptmEarlyAbortReason="GoodEnoughPlanFound">
                    <StatementSetOptions QUOTED_IDENTIFIER="true" ARITHABORT="false" CONCAT_NULL_YIELDS_NULL="true" ANSI_NULLS="true" …
Run Code Online (Sandbox Code Playgroud)

sql-server execution-plan

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

100% CPU 执行计划错误

由于特定查询使用了错误的执行计划,我遇到了 100% CPU 峰值的大问题。我现在花了几个星期自己解决。

我的数据库

我的示例数据库包含 3 个简化表。

[数据记录仪]

CREATE TABLE [model].[DataLogger](
    [ID] [bigint] IDENTITY(1,1) NOT NULL,
    [ProjectID] [bigint] NULL,
CONSTRAINT [PK_DataLogger] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
Run Code Online (Sandbox Code Playgroud)

【逆变器】

CREATE TABLE [model].[Inverter](
    [ID] [bigint] IDENTITY(1,1) NOT NULL,
    [SerialNumber] [nvarchar](50) NOT NULL,
 CONSTRAINT [PK_Inverter] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY],
 CONSTRAINT [UK_Inverter] UNIQUE NONCLUSTERED 
(
    [DataLoggerID] ASC,
    [SerialNumber] ASC
)WITH …
Run Code Online (Sandbox Code Playgroud)

performance execution-plan sql-server-2016 query-performance

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

StatementParameterizationType 计划属性是什么?

我注意到执行计划有时包含一个StatementParameterizationType属性。

属性窗口

这是什么,什么意思,什么时候出现?

sql-server ssms execution-plan

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

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

为什么聚集索引搜索会返回比基础表中的行数更高的“实际行数”?

我正在解决与 SQL Server(技术上是 Azure SQL 数据库)相关的问题,偶尔会选择错误的执行计划,大概是由于统计数据不准确。sp_updatestats每次都修复它,直到几个小时或几天后,一个糟糕的计划再次被缓存。

看着“糟糕”的计划,我注意到一些让我感到奇怪的事情:在当前大约有 170 万行的表上有一个聚集索引查找。此操作的“估计行数”约为 1200,这绝对符合我在这种情况下对该操作所期望的平均行数,但“实际行数”超过 6000 万!沿着这个叶节点的粗线,在所有 6000 万个节点上执行各种下游操作,例如连接和排序,导致过慢、溢出到 tempdb 和其他坏处。

我一定误解了聚集索引查找实际上是做什么的,因为我认为它不可能“输出”比基础表中更多的行。什么可能导致这种情况?更好的是,有关如何修复它的任何指示?

[包含诸如“sp_updatestats每次修复它但无法弄清楚如何永久修复它?阅读这篇文章”之类的奖励积分。这是我们最近在几个不同方面的普遍问题。]

sql-server optimization execution-plan azure-sql-database

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

如何更快地获得最近行的运行总数?

我目前正在设计一个事务表。我意识到需要计算每一行的运行总数,这可能会降低性能。所以我创建了一个包含 100 万行的表用于测试。

CREATE TABLE [dbo].[Table_1](
    [seq] [int] IDENTITY(1,1) NOT NULL,
    [value] [bigint] NOT NULL,
 CONSTRAINT [PK_Table_1] PRIMARY KEY CLUSTERED 
(
    [seq] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
Run Code Online (Sandbox Code Playgroud)

我试图获取最近的 10 行及其运行总数,但花了大约 10 秒。

--1st attempt
SELECT TOP 10 seq
    ,value
    ,sum(value) OVER (ORDER BY seq) total
FROM Table_1
ORDER BY seq DESC

--(10 rows affected)
--Table 'Worktable'. Scan count 1000001, logical reads 8461526, …
Run Code Online (Sandbox Code Playgroud)

performance database-design sql-server t-sql execution-plan query-performance

8
推荐指数
2
解决办法
474
查看次数

SQL Server 不使用索引

我对为什么我的查询没有使用我认为是选择性索引的东西感到非常困惑。

我的模型由索赔、联系人和电话号码组成。每个索赔有 1 个联系人,每个联系人都有许多电话号码。索赔可以有状态,电话号码有类型。 简化模型

我在状态的 Claim 上添加了一个索引,它包括 ContactID。

create index Status on tClaim(Status) include (Name,ContactID)
Run Code Online (Sandbox Code Playgroud)

我在电话上为 ContactID 和类型添加了一个索引,其中包括号码。

create index ContactID_Type on tContactPhone(ContactID,Type) include (Number)
Run Code Online (Sandbox Code Playgroud)

我正在尝试编写一个查询,该查询返回状态为“赢得”的所有索赔以及索赔联系人的相应“家庭电话”。我已经尝试了 2 种方法。一种包括加入通讯录,另一种没有。两者都不会产生我期望的计划。

select 
    c.ID,
    c.Name,
    p.Number 
from
     tClaim c 
     left join tContactPhone p on
        c.ContactID=p.ContactID and p.Type='Home'
where
    c.Status = 'Won'

select 
    c.ID,
    c.Name,
    p.Number
from
     tClaim c
     inner join tContact co on  
        co.id=c.ContactID
     left join tContactPhone p on
        co.ID=p.ContactID and p.Type='Home'
where
    c.Status = 'Won'
Run Code Online (Sandbox Code Playgroud)

我回来的计划拒绝使用 tContactPhone.ContactID_Type。它建议按类型索引,这没有意义,因为它似乎没有 ContactId 选择性。

粘贴计划

这是我用来创建要测试的示例数据集的脚本。请注意我的实际数据集要大得多,命名得更好,并且有更多的字段;但这被提炼出来以复制我的情况 [AKA 我什至不喜欢命名约定和数据生成,但它完成了工作:)] …

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

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

为什么 OPTION RECOMPILE 会导致谓词下推?

我有一个 SQL 查询,它是由一堆嵌套的视图和表值函数组成的,深度至少为 4 层(我没有时间或耐心去完成这一切,它有数百行代码在每个级别)。

我一直试图理解为什么当我使用选项(重新编译)运行基本查询时它运行得非常快,但是当我在没有这个选项的情况下运行它时,它运行得非常慢。

我已确保在发生这种情况之前清除计划缓存,即使在生成新计划时,它也不是最佳的,但是,选项(重新编译)速度很快。

我检查了这两个计划,并注意到对于带有选项(重新编译)的计划,传递的参数。

SELECT [p].[Activity]
    ,[p].[ActivityType]
    ,[p].[Company]
    ,[p].[Flags]
    ,[p].[Id]
    ,[p].[Name]
    ,[p].[Priority]
    ,[p].[Filters]
    ,[p].[Priority]
    ,[p].[Classification]
    ,[p].[Number]
    ,[p].[TaskFilter]
    ,[p].[TaskType]
    ,[p].[User]
FROM (
    SELECT *
    FROM [ActivProdStatuses]('ProdJobTask', 0)
    ) AS [p]
WHERE (
        (   ([p].[User] = 'some_value') AND (([p].[Flags] & 8) = 0) ) 
           AND ([p].[Activity] = 'unique_value') 
        )
    AND  
      (CASE 
        WHEN ([p].[Flags] & 4) <> 0
         THEN CAST(1 AS BIT)
         ELSE CAST(0 AS BIT)
       END = 1 )
ORDER BY [p].[Priority]
OPTION (RECOMPILE)
Run Code Online (Sandbox Code Playgroud)

在没有 OPTION …

sql-server execution-plan azure-sql-database recompile query-performance

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