标签: execution-plan

使用声明的变量时估计行非常错误

我正在非常非常错误的估计聚集索引寻求此查询的步骤(估计行是8637530;实际为74723):

Declare @StartDate as date = '10/1/2014';
Declare @EndDate as date = '10/2/2014';

select Sum(Quantity)
from Daily_GC_Items
where SalesDate between @StartDate and @EndDate;
Run Code Online (Sandbox Code Playgroud)

如果我对这样的日期使用字符串文字,则估计值几乎是完美的(估计行数为 75,337.4;实际为 74,723):

select Sum(Quantity)
from Daily_GC_Items
where SalesDate between '10/1/2014' and '10/2/2014'
Run Code Online (Sandbox Code Playgroud)

表定义:

[SalesDate] [date] NOT NULL,
[Store] [varchar](10) NOT NULL,
[GuestCheckNumber] [smallint] NOT NULL,
[ItemSequence] [smallint] NOT NULL,
[Quantity] [smallint] NOT NULL,
(Several more columns)
Run Code Online (Sandbox Code Playgroud)

首要的关键:

[SalesDate] ASC,
[Store] ASC,
[GuestCheckNumber] ASC,
[ItemSequence] ASC
Run Code Online (Sandbox Code Playgroud)

这种行为的可能原因是什么?

performance sql-server execution-plan sql-server-2014 cardinality-estimates query-performance

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

SQL Server 何时决定使用新索引?

我一直在运行公司购买的某些软件的服务器上进行一些维护,因此我无法真正更改查询的编写方式。我使用了一些工具来确定服务器上一些缺失的索引。但是,使用我的工具,我没有看到哪些查询指示了这些。但是,我确实会监视正在写入和读取的索引量。

所以,我的问题是,在添加已确定为缺失的新索引时,SQL Server 何时注意到新索引并确定它们是否真的有助于查询?是在创建索引后立即再次运行查询,还是更复杂?

performance sql-server execution-plan sql-server-2008-r2 index-tuning

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

为什么 SQL Server 查询计划在查询中不使用索引几乎类似于使用索引的查询?

我有两个结构相似的 UPDATE 查询,但其中一个的 SQL Server 查询计划显示正在使用的索引,而另一个仅显示常规表扫描。

以下是查询(根据查询计划,#1 不使用索引,#2 使用)-

 UPDATE Payment_Metadata 
    SET 
    Payment_Metadata.CommodityCode = 'RAW MATERIALS', 
    Payment_Metadata.C1 = 'RAW MATERIALS', 
    Payment_Metadata.C2 = 'INGREDIENTS', 
    Payment_Metadata.C3 = 'OTHER ', 
    Payment_Metadata.RuleText = '---', 
    Payment_Metadata.LastUpdatedIndex = Payment_Metadata.LastUpdatedIndex + 1, 
    Payment_Metadata.IsExcluded = 0, 
    Payment_Metadata.LogText = 'Commodity>Raw Materials>Ingredients>Other' 
    FROM 
    Payment_Metadata 
    WHERE 
    Payment_Metadata.IsProcessed = 0 
    AND (Payment_Metadata.EnrichedVendor = 'NFL' 
         OR Payment_Metadata.Vendor_No = 'NFL')
Run Code Online (Sandbox Code Playgroud)

第二个查询使用索引:

UPDATE Payment_Metadata 
SET 
Payment_Metadata.CommodityCode = 'RAW MATERIALS', 
Payment_Metadata.C1 = 'RAW MATERIALS', 
Payment_Metadata.C2 = 'INGREDIENTS', 
Payment_Metadata.C3 = 'OTHER ', 
Payment_Metadata.RuleText = '---', 
Payment_Metadata.LastUpdatedIndex = …
Run Code Online (Sandbox Code Playgroud)

sql-server execution-plan nonclustered-index

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

使用视图连接表或存储过程以获得更好的执行计划?

首先让我声明我是 C# 开发人员,而不是 SQL Server DBA,所以请原谅我对 SQL Server 数据库查询执行计划的无知。

我想知道的是对于使用主键和外键从两个或多个表中提取结果以引用它们的存储过程,是否更好的做法是:

  1. 有一个视图,视图执行连接并包含两个(或多个)表中所有相应记录的扁平化数据,并让存储过程从该视图中进行选择和过滤
  2. 存储过程进行连接和过滤

我问是因为在 C# 世界中,我们会将关注点分开,因此一个对象或函数将负责连接(在本例中为视图),另一个对象或函数将负责过滤(在本例中为存储过程) )。

  • 上面哪个选项会表现得更好?
  • 上面的哪个选项被认为是最佳实践?

在 C# 中,关注点分离通常被认为比性能更重要,直到证明性能已成为代码的严重问题。但是我不知道SQL世界里的东西堆起来了!

performance sql-server stored-procedures execution-plan view query-performance

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

聚合 GROUP BY 瓶颈

我有一个SELECT GROUP BY操作的性能瓶颈。

架构

我有一张这样的表:

CREATE TABLE [InverterData](
    [InverterID] [bigint] NOT NULL,
    [TimeStamp] [datetime] NOT NULL,    
    [ValueA] [decimal](18, 2) NULL,
    [ValueB] [decimal](18, 2) NULL
    CONSTRAINT [PrimaryKey_e149e28f-5754-4229-be01-65fafeebce16] PRIMARY KEY CLUSTERED 
    (
        [TimeStamp] DESC,
        [InverterID] ASC
    ) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF
    , IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON
    , ALLOW_PAGE_LOCKS = ON)
)
Run Code Online (Sandbox Code Playgroud)

Index这样的:

CREATE NONCLUSTERED INDEX [TimeStamp_Power-NonClusteredIndex] ON [dbo].[InverterData]
(
    [InverterID] ASC,
    [TimeStamp] ASC
)
INCLUDE 
(   
    [ValueA],
    [ValueB]
)
Run Code Online (Sandbox Code Playgroud)

[InverterData]表具有以下存储统计信息:

  • 数据空间:26,901.86 …

index sql-server-2008 sql-server execution-plan

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

查找哈希匹配聚合

阅读以下博客后,我明白hash match聚合原因blocking。使用适当的索引,它可以作为stream aggregate.

  1. 阻塞/非阻塞聚合运算符
  2. 聚合的阻塞性质 - Rob Farley
  3. 哈希聚合-Craig Freedman

我有一个数据库,其中包含 200 多个多年前创建的表。我正在尝试通过 group by 查找当前正在使用hash match聚合运算符的所有查询。我发现的一种可能性是使用 dmv,如下所示。但我不知道如何过滤它以仅列出带有hash match聚合运算符的查询。如何实现这一目标?此外,从大局来看,除了遵循 dmv 之外,还有哪些其他选项可以获取此信息?

SELECT cp.objtype AS ObjectType,
    OBJECT_NAME(st.objectid,st.dbid) AS ObjectName,
    cp.usecounts AS ExecutionCount,
    st.TEXT AS QueryText,
    qp.query_plan AS QueryPlan
FROM sys.dm_exec_cached_plans AS cp
CROSS APPLY sys.dm_exec_query_plan(cp.plan_handle) AS qp
CROSS APPLY sys.dm_exec_sql_text(cp.plan_handle) AS st
WHERE st.TEXT LIKE '%GROUP%'
Run Code Online (Sandbox Code Playgroud)

performance sql-server aggregate execution-plan performance-tuning

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

IN 子句 - 列表值和查询之间的性能差异

我改变了这个查询

SELECT ...
FROM linkedServer.DB.Schema.Table1 t1
LEFT JOIN linkedServer.DB.Schema.Table2 t2 ON t1.ORDER_ID = t2.ORDER_ID
WHERE t1.BRANCH_ID NOT IN (
        '009991', '009992', '009993', '009994', '009995', '009996', '009999', '900001', 
        '900002', '900003', '900004', '900005', '900006', '900007', '900008', '999991', 
        '999992', '999993', '999994', '999995'
        )
GROUP BY ...
Run Code Online (Sandbox Code Playgroud)

进入这个

SELECT ...
FROM linkedServer.DB.Schema.Table1 t1
LEFT JOIN linkedServer.DB.Schema.Table2 t2 ON t1.ORDER_ID = t2.ORDER_ID
WHERE t1.BRANCH_ID NOT IN (
        SELECT b.BRANCH_ID
        FROM TB_BRANCH b --25 rows in total
        WHERE b.START_DT = '99999999' --the result of this sub-query …
Run Code Online (Sandbox Code Playgroud)

performance sql-server optimization execution-plan

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

.Net 应用程序使用低效查询计划 - 由 ARITHABORT 设置引起?

我们的一个应用程序导致了一个问题,因为有一个存储过程在 SSMS 中返回正常,不到 1 秒,但在应用程序中,它最多需要 10 分钟,具体取决于使用的参数。任何参数组合在 SSMS 中都可以正常工作,执行计划对我来说看起来不错。

然而,当分析应用程序时,显然使用了不同的、效率较低的计划。用于连接的 SqlClient 具有 ARITHABORT 设置,设置为 OFF,当在 SSMS 中复制时,我遇到了相同的性能问题。

我猜 ARITHABORT OFF 将不允许优化器使用缓存计划?或者它运行一个单独的计划?

根据应用程序人员的说法,无法更改 SQLClient 连接以使用 ARITHABORT ON

我猜这里的 ARITHABORT 设置有点用词不当,它实际上是优化器没有使用好的计划导致的参数嗅探?

无论如何,我都需要强制它使用一个好的计划,那么如何最好地解决这个问题呢?我是否以某种方式创建计划指南或优化存储过程?

这是 SQL Server 2008R2 SP2。

performance sql-server execution-plan

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

选择运算符上的警告标志 - 这是什么意思?

在比较 2 个存储过程的执行计划时,在第二个存储过程中,我收到一个警告标志(由红色箭头标记)。

这是什么意思?

在此处输入图片说明

performance sql-server stored-procedures execution-plan sql-server-2014 query-performance

3
推荐指数
2
解决办法
1939
查看次数

合并连接性能调优

我一直在研究供应商 SQL 查询的性能问题,通常在这个供应商那里我可以看到可以提高性能的索引,但是这个查询目前在性能调整方面有点超出我的范围。希望在这个请求之后我会学到一些新东西。

SQL 的问题似乎是合并连接(内部连接),我不确定尝试和提高这些性能的最佳方法。

我真的很感激有人指出我正确的方向,或者如果我可以提供更多信息,请告诉我。

这是执行计划SQL 查询

由于我尝试应用索引,因此该索引并不多,但它们似乎没有减少合并连接的效果。因此,我给您的计划是使用供应商的默认索引。

更新 1:我添加了索引来查询,但它们几乎没有影响,这里是索引和新计划

新的 SQL 计划索引

我还更新了查询中涉及的所有表的统计信息。

使用选项(散列连接)将运行时间从 30 秒减少到 15 秒。但是,这是从屏幕后面运行的供应商 SQL,因此我无法强制执行此操作。

服务器上的 MAXDOP 设置为 0,成本阈值为 50,所以不确定为什么它不想并行。

更新 2:似乎在表 atstsehourdetmap 上具有以下唯一索引会导致问题。如果我删除这些,那么查询会在不到一秒的时间内运行。

创建唯一索引 [aiatstsehourdetmap2] ON [dbo].[atstsehourdetmap] ( [oid] ) ;

创建唯一索引 [aiatstsehourdetmap1] ON [dbo].[atstsehourdetmap] ( [tsehourdet_id] ) ;

任何想法为什么?

performance sql-server execution-plan query-performance

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