Questions tagged «execution-plan»

查询优化器选择的用于处理查询的策略。

4
为什么我的查询突然比昨天慢?
[薪水] (检查一项) [ ] Well trained professional, [ ] Casual reader, [ ] Hapless wanderer, 我有一个(选中所有适用项) [ ] query [ ] stored procedure [ ] database thing maybe 运行良好(如果适用) [ ] yesterday [ ] in recent memory [ ] at some point 但现在突然变慢了。 我已经检查过以确保它未被阻止,并且它不是某些长期运行的维护任务,报告或其他带外流程的受害者。 有什么问题,我应该怎么做,我可以提供什么信息以获得帮助? [*Insert appropriate closing remarks*]

4
索引搜索与索引扫描
在查看运行缓慢的查询的执行计划时,我注意到一些节点是索引查找,而某些节点是索引扫描。 索引搜索和索引扫描之间有什么区别? 哪个表现更好? SQL如何选择一个? 我意识到这是3个问题,但我认为回答第一个问题将解释其他问题。

3
过多的排序内存授予
为什么这个简单的查询被授予这么多的内存? -- Demo table CREATE TABLE dbo.Test ( TID integer IDENTITY NOT NULL, FilterMe integer NOT NULL, SortMe integer NOT NULL, Unused nvarchar(max) NULL, CONSTRAINT PK_dbo_Test_TID PRIMARY KEY CLUSTERED (TID) ); GO -- 100,000 example rows INSERT dbo.Test WITH (TABLOCKX) (FilterMe, SortMe) SELECT TOP (100 * 1000) CHECKSUM(NEWID()) % 1000, …

3
参数嗅探vs变量vs重新编译vs优化未知
因此,我们有一个长时间运行的进程,导致今天早晨出现问题(30秒+运行时间)。我们决定检查是否应该归因于参数嗅探。因此,我们重写了proc并将输入的参数设置为变量,以消除参数嗅探。一种尝试/正确的方法。Bam,查询时间得到改善(不到1秒)。在查看查询计划时,在原始索引未使用的索引中发现了改进。 只是为了验证我们没有得到误报,我们对原始proc进行了dbcc freeproccache,然后重新运行以查看改进的结果是否相同。但是,令我们惊讶的是,原始过程仍然运行缓慢。我们再次使用WITH RECOMPILE进行了尝试,但仍然很慢(我们在对proc的调用以及在proc自身内部尝试了重新编译)。我们甚至重新启动了服务器(显然是dev框)。 所以,我的问题是...当我们在空的计划缓存上收到相同的慢查询时,怎么应该怪参数嗅探呢?snif应该没有任何参数? 我们是否会受到与计划缓存无关的表统计信息的影响?如果是这样,为什么将传入参数设置为变量会有所帮助呢? 在进一步的测试中,我们还发现在proc DID的内部插入OPTION(优化未知)会获得预期的改进计划。 因此,你们中有些人比我聪明,您能否提供一些线索,以了解产生这种类型结果的幕后情况? 另一个要注意的是,慢速计划也有理由提前中止,GoodEnoughPlanFound而快速计划在实际计划中没有早期中止原因。 综上所述 从传入参数中创建变量(1秒) 重新编译(30秒以上) dbcc freeproccache(30+秒) 选项(为不知道而优化)(1秒) 更新: 请在此处查看慢速执行计划:https: //www.dropbox.com/s/cmx2lrsea8q8mr6/plan_slow.xml 在此处查看快速执行计划:https : //www.dropbox.com/s/b28x6a01w7dxsed/plan_fast.xml 注意:出于安全原因,表,架构,对象名称已更改。

3
执行计划基础-哈希匹配混乱
我开始学习执行计划,并对哈希匹配的工作原理以及为什么在简单的联接中使用它感到困惑: select Posts.Title, Users.DisplayName From Posts JOIN Users on Posts.OwnerUserId = Users.Id OPTION (MAXDOP 1) 据我了解,顶部索引扫描的结果变为具有哈希功能,并且底部索引群集扫描的每一行都被查找。我了解哈希表至少在某种程度上是如何工作的,但是在这样的示例中,我对哪些值确切地被哈希感到困惑。 对我来说有意义的是,它们之间的公共字段id被散列了-但是,如果是这种情况,为什么还要散列一个数字呢?

2
TOP如何(以及为什么)影响执行计划?
对于我要优化的中等复杂查询,我注意到删除该TOP n子句会更改执行计划。我可能已经猜到,当查询中包含TOP n数据库引擎时,该查询将忽略该TOP子句而运行,然后最后仅将结果集缩减为所请求的n行。图形化的执行计划似乎表明是这种情况,这是TOP“最后一步”。但似乎还有更多的事情正在进行。 我的问题是,TOP n子句如何(以及为什么)影响查询的执行计划? 这是我的情况的简化版本: 该查询匹配两个表A和B中的行。 如果没有该TOP子句,优化器估计表A将有19k行,表B将有46k行。对于A,返回的实际行数是16k,对于B,返回的行数是13k。散列匹配用于将两个结果集连接到a总共69行(然后应用排序)。这个查询很快发生。 当我添加TOP 1001优化器时,不使用哈希匹配;相反,它首先对表A的结果进行排序(相同的估计值/实际值为19k / 16k),并针对表B进行嵌套循环。表B的估计行数现在为1,奇怪的是,TOP n直接影响表B 针对B的估计执行次数(索引查找)-始终为2n + 1,在我的情况下为2003。如果我更改,则此估计值也会相应更改TOP n。当然,由于这是嵌套联接,因此实际执行次数为16k(表A中的行数),这会使查询速度变慢。 实际情况要复杂一些,但这捕获了基本思想/行为。使用索引查找来搜索两个表。这是SQL Server 2008 R2企业版。

2
使用XML阅读器优化计划
从此处执行查询以将死锁事件从默认扩展事件会话中拉出 SELECT CAST ( REPLACE ( REPLACE ( XEventData.XEvent.value ('(data/value)[1]', 'varchar(max)'), '<victim-list>', '<deadlock><victim-list>'), '<process-list>', '</victim-list><process-list>') AS XML) AS DeadlockGraph FROM (SELECT CAST (target_data AS XML) AS TargetData FROM sys.dm_xe_session_targets st JOIN sys.dm_xe_sessions s ON s.address = st.event_session_address WHERE [name] = 'system_health') AS Data CROSS APPLY TargetData.nodes ('//RingBufferTarget/event') AS XEventData (XEvent) …



3
内联变量时,为什么SQL Server使用更好的执行计划?
我有一个要优化的SQL查询: DECLARE @Id UNIQUEIDENTIFIER = 'cec094e5-b312-4b13-997a-c91a8c662962' SELECT Id, MIN(SomeTimestamp), MAX(SomeInt) FROM dbo.MyTable WHERE Id = @Id AND SomeBit = 1 GROUP BY Id MyTable 有两个索引: CREATE NONCLUSTERED INDEX IX_MyTable_SomeTimestamp_Includes ON dbo.MyTable (SomeTimestamp ASC) INCLUDE(Id, SomeInt) CREATE NONCLUSTERED INDEX IX_MyTable_Id_SomeBit_Includes ON dbo.MyTable (Id, SomeBit) INCLUDE (TotallyUnrelatedTimestamp) 当我完全按照上面的描述执行查询时,SQL Server将扫描第一个索引,从而导致189,703逻辑读取和2-3秒的持续时间。 当我内联@Id变量并再次执行查询时,SQL Server将查找第二个索引,从而导致仅104次逻辑读取和0.001秒的持续时间(基本上是即时的)。 我需要变量,但是我希望SQL使用好的计划。作为一个临时解决方案,我在查询上添加了索引提示,查询基本上是即时的。但是,我尽量避免使用索引提示。我通常假设如果查询优化器无法完成其工作,那么我可以做一些事情(或停止做些事情)来帮助它,而无需明确告诉它该做什么。 …

1
SQL Server 2014:有关不一致的自连接基数估计的任何解释?
考虑SQL Server 2014中的以下查询计划: 在查询计划中,自联接ar.fId = ar.fId产生的估计值为1行。但是,这在逻辑上是不一致的估计:ar只有20,608行,并且只有一个不同的值fId(准确地反映在统计数据中)。因此,此联接产生行(~424MMrow)的全叉积,导致查询运行几个小时。 我很难理解为什么SQL Server会提出一个很容易证明与统计数据不一致的估计。有任何想法吗? 初步调查和其他细节 根据Paul 在这里的答案,似乎用于估计联接基数的SQL 2012和SQL 2014启发式方法应该可以轻松处理需要比较两个相同直方图的情况。 我从跟踪标志2363的输出开始,但无法轻松理解。下面的代码段是否表示SQL Server正在比较的直方图fId和bId以便估计仅使用的联接的选择性fId?如果是这样,那显然是不正确的。还是我误读了跟踪标志输出? Plan for computation: CSelCalcExpressionComparedToExpression( QCOL: [ar].fId x_cmpEq QCOL: [ar].fId ) Loaded histogram for column QCOL: [ar].bId from stats with id 3 Loaded histogram for column QCOL: [ar].fId from stats with id 1 Selectivity: 0 请注意,我想出了几种变通办法,这些变通办法包含在完整的repro脚本中,并将此查询缩短为毫秒。这个问题的重点是了解行为,如何在以后的查询中避免它,以及确定它是否应与Microsoft一起提交。 …

3
持久计算列上的索引需要键查找才能获取计算表达式中的列
此问题是从Stack Overflow 迁移而来的,因为可以在Database Administrators Stack Exchange上回答。 迁移 6年前。 我在表上有一个持久的计算列,该表只是由串联的列组成,例如 CREATE TABLE dbo.T ( ID INT IDENTITY(1, 1) NOT NULL CONSTRAINT PK_T_ID PRIMARY KEY, A VARCHAR(20) NOT NULL, B VARCHAR(20) NOT NULL, C VARCHAR(20) NOT NULL, D DATE NULL, E VARCHAR(20) NULL, Comp AS A + '-' + B + '-' …

1
向用户授予SQL Server SHOWPLAN权限有任何风险吗?
此问题是从Stack Overflow 迁移而来的,因为可以在Database Administrators Stack Exchange上回答。 迁移 7年前。 我正在对大型SQL Server 2008数据库进行性能调整,并且IT小组不愿意授予SHOWPLAN权限。过去,“显示执行计划”一直是了解单个查询和过程的性能的最有效方法。 授予此许可有哪些固有风险?对数据库的开发副本进行此限制是否有合理的理由? 注意:该SQL IT组在一个SQL Server实例下有200多个数据库。谢谢。 答:我认为缺乏响应是指除以下所述之外,没有重大的安全风险。基本上,将其限制在开发数据库上会适得其反。 如果有人想出更好的答案,我将进行更新。感谢您的意见!


1
普通的SELECT查询计划中的“恒定扫描”和“左外部联接”来自何处?
我有这张桌子: CREATE TABLE [dbo].[Accounts] ( [AccountId] UNIQUEIDENTIFIER UNIQUE NOT NULL DEFAULT NEWID(), -- WHATEVER other columns ); GO CREATE UNIQUE CLUSTERED INDEX [AccountsIndex] ON [dbo].[Accounts]([AccountId] ASC); GO 该查询: DECLARE @result UNIQUEIDENTIFIER SELECT @result = AccountId FROM Accounts WHERE AccountId='guid-here' 使用包含单个“索引搜索”的查询计划执行-符合预期: SELECT <---- Clustered Index Seek 该查询的作用相同: DECLARE @result UNIQUEIDENTIFIER SET …

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.