标签: execution-plan

外部应用与左连接与派生表中的聚合

考虑以下设置。涉及三个表#CCP_DETAILS_TEMPPeriod并且ACTUALS_DETAILS

#CCP_DETAILS_TEMP会有50000记录,ACTUALS_DETAILS可以有5000000记录,period表会有2000记录

指数详情:

CREATE UNIQUE CLUSTERED INDEX IX_CCP_DETAILS_TEMP
  ON #CCP_DETAILS_TEMP (CCP_DETAILS_SID)

CREATE NONCLUSTERED INDEX IXN_ACTUALS_DETAILS_PERIOD_SID_RS_MODEL_SID_CCP_DETAILS_SID_QUANTITY_INCLUSION
  ON ACTUALS_DETAILS (PERIOD_SID, CCP_DETAILS_SID, RS_MODEL_SID, QUANTITY_INCLUSION)
  INCLUDE( SALES, QUANTITY, DISCOUNT) 

CREATE UNIQUE CLUSTERED INDEX IX_PERIOD
  ON PERIOD (PERIOD_SID)
Run Code Online (Sandbox Code Playgroud)

我有一个要求,我为此编写了三种不同的方法来实现结果。现在我想知道哪个更好。

所有三个查询都或多或少地同时运行。我需要一些专家的建议,以了解哪一个会表现得更好。任何一种方法都有什么缺点吗

方法一: Outer Apply

花的时间: 4615 Milli Seconds

SELECT c.CCP_DETAILS_SID,
       A.PERIOD_SID,
       SALES,
       QUANTITY
FROM   #CCP_DETAILS_TEMP c
       CROSS JOIN (SELECT PERIOD_SID
                   FROM   BPIGTN_GAL_APP_DEV_ARM..PERIOD
                   WHERE  PERIOD_SID BETWEEN 577 AND 624)A
       OUTER apply …
Run Code Online (Sandbox Code Playgroud)

performance sql-server execution-plan sql-server-2012

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

左外连接 - 查询计划中的排序操作 - 有什么方法可以调整这个简单的查询?

在处理以下查询以回答此问题时:

如何以数据库不可知的方式查询图表数据?

有以下表格:

CREATE TABLE [dbo].[#foo] ( 
[creation]  DATETIME                         NOT NULL,
[value]     MONEY                                NULL,
[DT]        AS (CONVERT([date],[CREATION])) PERSISTED)


-- add a clustered index on the dt column
CREATE CLUSTERED INDEX CI_FOO ON #FOO(DT)
GO
Run Code Online (Sandbox Code Playgroud)

和另一个加入表:

create table #bar (dt date primary key clustered)
go
Run Code Online (Sandbox Code Playgroud)

可以在此处找到将数据加载到这些表中

但是在运行以下查询时:

WITH RADHE AS (
SELECT THE_ROW=ROW_NUMBER() OVER(PARTITION BY B.DT ORDER BY B.DT),
       THE_DATE=B.dt,
       THE_NUMBER_OF_RECORDS_ON_THIS_DAY=CASE WHEN F.DT IS NULL THEN 0 ELSE COUNT(*) OVER (PARTITION BY F.DT ) END ,
       THE_TOTAL_VALUE_FOR_THE_DAY=COALESCE(SUM(F.VALUE) OVER (PARTITION BY …
Run Code Online (Sandbox Code Playgroud)

performance sql-server optimization execution-plan sort-operator query-performance

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

神秘的条件 where 子句索引选择

你有没有解释一下,为什么查询优化器在这个例子中选择了不同的索引和模式?

/* crete objects and data for testing */

-- table
CREATE TABLE #Test (
    ID INT IDENTITY PRIMARY KEY
    ,CustNo INT NULL
    ,CustNo2 INT NULL
    );

-- populate with data
WITH
  L0   AS(SELECT 1 AS c UNION ALL SELECT 1),
  L1   AS(SELECT 1 AS c FROM L0 AS A CROSS JOIN L0 AS B),
  L2   AS(SELECT 1 AS c FROM L1 AS A CROSS JOIN L1 AS B),
  L3   AS(SELECT 1 AS c FROM L2 AS A CROSS JOIN …
Run Code Online (Sandbox Code Playgroud)

sql-server optimization t-sql execution-plan

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

具有聚集索引的表按唯一非聚集索引隐式排序

我有一个表,用于捕获用户正在运行的主机平台。该表的定义很简单:

IF OBJECT_ID('[Auth].[ActivityPlatform]', 'U') IS NULL
BEGIN
    CREATE TABLE [Auth].[ActivityPlatform] (
        [ActivityPlatformId] [tinyint] IDENTITY(1,1) NOT NULL
        ,[ActivityPlatformName] [varchar](32) NOT NULL
        ,CONSTRAINT [PK_ActivityPlatform] PRIMARY KEY CLUSTERED ([ActivityPlatformId] ASC)
        ,CONSTRAINT [UQ_ActivityPlatform_ActivityPlatformName] UNIQUE NONCLUSTERED ([ActivityPlatformName] ASC)
    ) ON [Auth];
END;
GO
Run Code Online (Sandbox Code Playgroud)

它存储的数据是基于 JavaScript 方法枚举的,该方法使用来自浏览器的信息(我不知道更多,但可以在需要时找到):

平台

但是,当我在SELECT没有显式的情况下执行基本操作ORDER BY时,执行计划显示它正在使用UNIQUE NONCLUSTERED索引而不是CLUSTERED索引进行排序。

SELECT * FROM [Auth].[ActivityPlatform] 
Run Code Online (Sandbox Code Playgroud)

非集群缓存

当显式指定 时ORDER BY,它正确地按 排序ActivityPlatformId

SELECT * FROM [Auth].[ActivityPlatform] ORDER BY [ActivityPlatformId]
Run Code Online (Sandbox Code Playgroud)

集群缓存

DBCC SHOWCONTIG('[Auth].[ActivityPlatform]') WITH ALL_LEVELS, TABLERESULTS 显示没有表碎片。

我错过了什么可能导致这个?我一直认为该表是在聚集索引上创建的,它应该自动隐式地对其进行排序,而无需指定ORDER BY …

performance index sql-server execution-plan query-performance

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

将 IN 与 EXISTS 交换会产生不同的结果集

我正在尝试更新使用子句谓词中的IN运算符的查询,以比较潜在的性能改进并更好地了解当两者互换时幕后发生的事情。这是我的理解,在实践中,查询优化器对待,并以同样的方式时,它可以。WHEREEXISTSEXISTSIN

我注意到当使用IN运算符运行查询时,它返回所需的结果集。但是,当我用EXISTS等效项替换它时,它会从我要过滤的主表中提取所有值。它忽略传递给EXISTS (SELECT ...并返回所有可能的不同值的提供的输入值。

用例相对简单:查询接受一个管道分隔的@Series字符串,最多可以包含 4 个值,例如S1|S2|S3|S4S2|S4。在这里,我string_split将输入到一个表中的变量@SeriesSplit,以确定相应的内部[SeriesId][Series]。然后过滤返回的结果集以排除[Series]未通过的结果。

为了说明,这里有一个类似的表定义:

DROP TABLE IF EXISTS [dbo].[Document]
IF OBJECT_ID('[dbo].[Document]', 'U') IS NULL
BEGIN
    CREATE TABLE [dbo].[Document] (
        [DocumentId] bigint IDENTITY(1,1) NOT NULL
        ,[DocumentSeriesId] [tinyint] NOT NULL
        ,CONSTRAINT [PK_Document] PRIMARY KEY CLUSTERED ([DocumentId] ASC)
        ,INDEX [IX_Document_SeriesId] NONCLUSTERED ([DocumentSeriesId] ASC)
    );
END;
GO
Run Code Online (Sandbox Code Playgroud)

用虚拟数据填充测试表。

SET IDENTITY_INSERT [dbo].[Document] ON; …
Run Code Online (Sandbox Code Playgroud)

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

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

并行度和调度器使用

以有效并行度 运行的 SQL Server 查询是否有可能x将并行工作器分配给多个x不同的调度程序?即使执行计划有许多并行区域?

sql-server parallelism execution-plan

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

sp_executesql 中查询的执行时间很长

我有一个从 .net 应用程序生成的查询,参数是 linq 参数。我用来调整查询的过程如下。

  • 我运行应用程序并使用探查器捕获查询。
  • 查询的形式是

    exec sp_executesql N'SELECT 
    [Extent1].[Id] AS [Id], 
    [Extent1].[GroupId] AS [GroupId], 
    [Extent1].[Agency] AS [Agency], 
    [Extent1].[Group] AS [Group], 
    [Extent1].[Claim] AS [Claim], 
    [Extent1].[StartDate] AS [StartDate], 
    [Extent1].[ExpireDate] AS [ExpireDate], 
    [Extent1].[IsActive] AS [IsActive]
    FROM [dbo].[Permissions] AS [Extent1]
    WHERE ([Extent1].[GroupId] = @p__linq__0) AND (([Extent1].[ExpireDate] IS NULL)
    OR ([Extent1].[ExpireDate] > @p__linq__1)) AND ([Extent1].[IsActive] <> 1)',
    N'@p__linq__0 int,@p__linq__1 datetime2(7)',
    @p__linq__0=15,@p__linq__1='2017-05-10 00:00:00'
    
    Run Code Online (Sandbox Code Playgroud)

这只是一个示例查询。实际查询要大得多,并且包括许多涉及多个视图和表等的连接。

我的问题是:

  • 按原样运行查询时,执行时间约为 15 秒
  • 当我单独取出查询sp_executesql并将过滤器值应用于查询时,它会在不到 1 秒的时间内运行。

我知道由于这些值是硬编码到查询中的,所以它会更快,但为什么执行时间会有这么大的差异?两者的执行计划也不同:

带有 sp_executesql 的 SQL 执行计划

使用硬编码 SQL 的执行计划

我是在这台服务器上工作的唯一用户,我在两种情况下都执行相同的参数。我已经申请OPTION(RECOMPILE) …

performance sql-server dynamic-sql execution-plan query-performance

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

理解执行计划的问题

我不熟悉 SQL Server 中的执行计划,我试图了解 SQL Server 执行某些操作的原因。查询是:

select P.PERSONID
from KSS_V_EMPLEADOS_PER_3_CERRADOS p, COMBHOMEACCT c, LABORACCT L, kss_carga_empl_centros k, CALENDAR ca
where p.PERSONID = c.EMPLOYEEID
and c.LABORACCTID = l.LABORACCTID
and k.empleado = p.PERSONNUM
and convert(date,ca.CALENDARDTM,103) between DBO.KSS_PrimerDiaMes(convert(DATE,@DFECHA, 103)) and DBO.KSS_UltimoDiaMes(convert (DATE,@DFECHA, 103))
and convert(date,ca.CALENDARDTM,103) between p.Inicio and p.Fin
and convert(date,ca.CALENDARDTM,103) between convert(date,c.EFFECTIVEDTM,103) and convert(date,c.EXPIRATIONDTM-1,103)
and convert(date,ca.CALENDARDTM,103) between k.FECHA_INI and k.FECHA_FIN
and l.LABORLEV4NM <> k.CENTRO
Run Code Online (Sandbox Code Playgroud)

表信息

  • KSS_V_EMPLEADOS_PER_3_CERRADOS是一个没有索引的视图,涉及一些表和函数。它有 12827 行

  • COMBHOMEACCT c 是一个有 16771 行的表

  • LABORACCT 是一个有 2460 行的表

  • kss_carga_empl_centros 是一个有 6594 …

sql-server optimization execution-plan

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

巨大的内存授予导致 RESOURCE SEMAPHORE 等待其他查询

问题:

我有几个查询需要大量内存授权(~7GB)。这些查询经常运行,这导致其他查询等待内存。所以我看到 RESOURCE_SEMAPHORE 等待类型。服务器信息:

  1. Microsoft SQL Server 2016 (SP2) (KB4052908) - Windows Server 2016 Standard 10.0(内部版本 14393:)上的 13.0.5026.0 (X64)
  2. 128 GB 内存
  3. 96 GB 作为最大服务器内存
  4. 数据库大小为 1.6 TB
  5. 启用事务复制
  6. 查询存储已禁用

我知道我已经发布了有关此服务器性能的类似问题。我试图从不同的角度看待事物或尝试以不同的方式解决问题。正如这篇文章中提到的,我有某种内存压力。现在我正在尝试修复查询中的问题或摆脱这个巨大的内存授权。

这是帖子中提到的查询的计划。

执行计划

我了解到这SORT,HASH JOIN,EXCHANGE(parallel Distribute Stream and Parallel Re partition stream and Parallel Gather Stream)是消耗内存的迭代器,我在我的执行计划中看到了这些。

我怎样才能从这个查询中减少这个巨大的内存授权。?甚至我也很困惑内存压力是否是由于大量查询授予的巨大内存造成的。?

这是我使用 SQLServer 探查器捕获查询时的实际查询。

exec sp_executesql N'SELECT TOP (@p__linq__6) 
    [PJ2].[FormId] AS [FormId], 
    [PJ2].[TNUMId] AS [TNUMId], 
    [PJ2].[TNUMDateTime] AS [TNUMDateTime], 
    [PJ2].[TNUMEventNumber] AS [TNUMEventNumber], 
    [PJ2].[EventNumber] AS [EventNumber], 
    [PJ2].[SubUnit] AS [SubUnit], 
    [PJ2].[EventClass] AS [EventClass], …
Run Code Online (Sandbox Code Playgroud)

performance sql-server execution-plan memory-grant query-performance

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

由于此查询中定义的提示,查询处理器无法生成查询计划

有一个类似的问题,但不一样:

查询处理器无法生成查询计划

我有以下查询和以下过滤索引,但我看不出该查询无法使用下面描述的过滤索引的任何原因:

- 查询 - 使用max列或仅使用列都没有关系,它不喜欢索引提示

SELECT -- MAX(AC1.changeDate)   
          AC1.changeDate
          FROM [dbo].[applicationStateChange]  AS ac1  WITH(INDEX(FI_ASC_ChangeDate))  
          WHERE ac1.applicationID = 130002
          AND AC1.newStatus = 'PLC'  
Run Code Online (Sandbox Code Playgroud)

-- 这是我的过滤索引 - 这个索引只是为了优化上面的查询

CREATE NONCLUSTERED INDEX FI_ASC_ChangeDate  
ON [dbo].[applicationStateChange] (   applicationID DESC)  
INCLUDE ( [changeDate] )
WHERE newStatus = 'PLC'  
WITH (  PAD_INDEX = OFF, FILLFACTOR = 100  , SORT_IN_TEMPDB = OFF , IGNORE_DUP_KEY = OFF, STATISTICS_NORECOMPUTE = OFF, ONLINE = On, 
DROP_EXISTING = ON, 
DATA_COMPRESSION=PAGE, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON ) …
Run Code Online (Sandbox Code Playgroud)

index optimization execution-plan filtered-index sql-server-2016

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