我知道出于性能原因应该避免它,但我试图展示一个条件,它显示为演示如何确保它不会出现。
但是,我最终得到了缺少索引警告,但优化器选择不创建临时索引。
我正在使用的查询是
SELECT
z.a
FROM dbo.t5 AS z WITH(INDEX(0))
WHERE
EXISTS
(
SELECT y.a
FROM dbo.t4 AS y
WHERE y.a = z.a
)
OPTION (MAXDOP 1);
Run Code Online (Sandbox Code Playgroud)
表模式是:
CREATE TABLE dbo.t4
(
a integer NULL,
b varchar(1000) NULL,
p varchar(100) NULL
);
CREATE TABLE dbo.t5
(
a integer NULL,
b varchar(1000) NULL
);
CREATE UNIQUE CLUSTERED INDEX c1
ON dbo.t5 (a);
Run Code Online (Sandbox Code Playgroud)
两个表都有 10,000 行,您可以使用以下方法进行模拟:
UPDATE STATISTICS dbo.t4
WITH
ROWCOUNT = 10000,
PAGECOUNT = 1000;
UPDATE STATISTICS dbo.t5
WITH
ROWCOUNT = …Run Code Online (Sandbox Code Playgroud) 我刚刚在我的网站http://sqlfiddle.com上推出了一项功能,允许用户查看其查询的原始执行计划。对于 PostgreSQL、MySQL 和(在某种程度上)Oracle,查看原始执行计划输出似乎很容易理解。但是,如果您查看 SQL Server 的执行计划输出(使用 生成SET SHOWPLAN_XML ON),即使对于相对简单的查询,也有大量的 XML 需要处理。这是一个示例(取自此“小提琴”的最后一个查询的执行计划:http : //sqlfiddle.com/#!3/ 1fa93/1):
<ShowPlanXML xmlns="http://schemas.microsoft.com/sqlserver/2004/07/showplan" Version="1.1" Build="10.50.2500.0">
<BatchSequence>
<Batch>
<Statements>
<StmtSimple StatementText="
select * from supportContacts" StatementId="1" StatementCompId="1" StatementType="SELECT" StatementSubTreeCost="0.0032853" StatementEstRows="3" StatementOptmLevel="TRIVIAL" QueryHash="0x498D13A3874D9B6E" QueryPlanHash="0xD5DDBD3C2D195E96">
<StatementSetOptions QUOTED_IDENTIFIER="true" ARITHABORT="false" CONCAT_NULL_YIELDS_NULL="true" ANSI_NULLS="true" ANSI_PADDING="true" ANSI_WARNINGS="true" NUMERIC_ROUNDABORT="false"/>
<QueryPlan CachedPlanSize="16" CompileTime="0" CompileCPU="0" CompileMemory="72">
<RelOp NodeId="0" PhysicalOp="Clustered Index Scan" LogicalOp="Clustered Index Scan" EstimateRows="3" EstimateIO="0.003125" EstimateCPU="0.0001603" AvgRowSize="42" EstimatedTotalSubtreeCost="0.0032853" TableCardinality="3" Parallel="0" EstimateRebinds="0" EstimateRewinds="0">
<OutputList>
<ColumnReference Database="[db_1fa93]" Schema="[dbo]" Table="[supportContacts]" Column="id"/>
<ColumnReference Database="[db_1fa93]" Schema="[dbo]" Table="[supportContacts]" …Run Code Online (Sandbox Code Playgroud) OFFSET ... FETCHSQL Server 2012 引入的新模型提供了简单且快速的分页。考虑到这两种形式在语义上相同且非常常见,为什么会有任何差异?
人们会假设优化器可以识别两者并将它们(简单地)优化到最大程度。
这是一个非常简单的案例,OFFSET ... FETCH根据成本估算,速度提高了约 2 倍。
SELECT * INTO #objects FROM sys.objects
SELECT *
FROM (
SELECT *, ROW_NUMBER() OVER (ORDER BY object_id) r
FROM #objects
) x
WHERE r >= 30 AND r < (30 + 10)
ORDER BY object_id
SELECT *
FROM #objects
ORDER BY object_id
OFFSET 30 ROWS FETCH NEXT 10 ROWS ONLY
Run Code Online (Sandbox Code Playgroud)

可以通过创建 CIobject_id或添加过滤器来改变此测试用例,但不可能消除所有计划差异。OFFSET ... FETCH总是更快,因为它在执行时做的工作更少。
sql-server optimization execution-plan sql-server-2012 offset-fetch
我正在查看计划缓存,寻找低悬的优化成果,并发现了以下代码段:

为什么很多费用都在 100% 以上?那应该是不可能的吧?
如果您使用“包括实际执行计划”运行查询,该计划还将建议缺少的索引。索引详细信息MissingIndexes位于 XML 中的标记内。是否存在计划包含多个索引建议的情况?我尝试了不同的 sql 查询,但无法提出任何生成两个或多个缺失索引的查询。
我正在尝试对 SQL Server 2014 Enterprise 中的查询进行性能优化。
我已经在 SQL Sentry Plan Explorer 中打开了实际的查询计划,我可以在一个节点上看到它有一个Seek Predicate和一个Predicate
什么之间的区别寻求谓词和谓词?
注意:我可以看到这个节点有很多问题(例如估计行与实际行、剩余 IO),但问题与任何这些都无关。
performance execution-plan sql-server-2014 query-performance
在我们的一个数据库中,我们有一个由多个线程密集并发访问的表。线程确实通过MERGE. 还有一些线程偶尔会删除行,因此表数据非常不稳定。执行 upsert 的线程有时会陷入死锁。该问题看起来与此问题中描述的问题相似。不过,不同之处在于,在我们的例子中,每个线程都只更新或插入一行。
简化设置如下。该表是堆,上面有两个唯一的非聚集索引
CREATE TABLE [Cache]
(
[UID] uniqueidentifier NOT NULL CONSTRAINT DF_Cache_UID DEFAULT (newid()),
[ItemKey] varchar(200) NOT NULL,
[FileName] nvarchar(255) NOT NULL,
[Expires] datetime2(2) NOT NULL,
CONSTRAINT [PK_Cache] PRIMARY KEY NONCLUSTERED ([UID])
)
GO
CREATE UNIQUE INDEX IX_Cache ON [Cache] ([ItemKey]);
GO
Run Code Online (Sandbox Code Playgroud)
典型的查询是
DECLARE
@itemKey varchar(200) = 'Item_0F3C43A6A6A14255B2EA977EA730EDF2',
@fileName nvarchar(255) = 'File_0F3C43A6A6A14255B2EA977EA730EDF2.dat';
MERGE INTO [Cache] WITH (HOLDLOCK) T
USING (
VALUES (@itemKey, @fileName, dateadd(minute, 10, sysdatetime()))
) S(ItemKey, FileName, Expires)
ON …Run Code Online (Sandbox Code Playgroud) 在 SQL Server 中有几种假脱机。我感兴趣的两个是Table Spool s 和Index spools,在修改查询之外。
只读查询,特别是在嵌套循环连接的内侧,可以使用表或索引假脱机来潜在地减少 I/O 并提高查询性能。这些线轴可以是Eager或Lazy。就像你我一样。
我的问题是:
SentryOne Plan Explorer是否像宣传的那样工作,是否合法?有什么问题或需要担心的事情吗?
与 SSMS 对估计执行计划视图的噩梦相比,它似乎以颜色显示了热路径。
我担心的是 - 它是否恶意或以其他方式修改任何数据?
编辑:我刚刚听说过它,以前从未听说过这家公司。
performance sql-server optimization execution-plan query-performance
我们的生产环境有这个问题。
Microsoft SQL Server 2008 R2 (SP1) - 10.50.2500.0 (X64) - Windows NT 6.1(内部版本 7601:Service Pack 1)上的企业版(64 位)。
SQL Server 正在删除所有(几乎 100%)旧的执行计划,并在每天夜间(从晚上 11:00 到早上 8:00)重新创建它们。当“自动更新统计信息”处于禁用状态时,甚至会发生这种情况。在过去的 2-3 周内,我们已经开启了“自动更新统计信息”。但它仍在发生。
我们真的不知道是什么触发了这种重新生成计划,但我们确信我们不会手动进行。
唯一真正与计划重新生成时间一致的是我们的数据库维护工作:每日索引重组(碎片为 5-30% 时),以及每日索引重建(碎片超过 30% 时) ) 工作。通常这个日常维护工作只做重组(因为每天的索引碎片永远不会超过 30%)。
影响:
这些新创建的计划使一些 UDF 调用/查询调用(从 UI/网页调用)花费更长的时间(分钟而不是不到 1 秒),因此会话只会堆积起来,使 CPU 接近 90% .
当那些卡住的会话被强行删除(在 DB 端)时,问题就会消失,并且 1)当所有相应的执行计划被手动清除(对于查询)或 2)当 UDF 被更改(对于函数)时。从那一刻起,SQL 服务器创建的任何新计划都会在一天中完美运行,直到第二天早上最终出现相同的问题。此外,这种行为并不是 100% 一致的,我们并不是每天早上都能看到它。但是有一段时间我们已经连续 4-5 天看到它了。
问题发生在工作日的早晨,这似乎是更频繁地访问 UI/网页的时候。
有没有人知道是什么导致了这个问题以及如何解决这个问题?任何帮助将非常感激。
execution-plan ×10
sql-server ×8
optimization ×2
performance ×2
deadlock ×1
index ×1
index-spool ×1
merge ×1
offset-fetch ×1
ssms ×1
statistics ×1
t-sql ×1