我正在对性能问题进行故障排除并尝试为报告查询获得稳定的执行计划。实际计划的链接如下:
如果您查看 Good 计划,则排序是在表连接之后进行的。对于糟糕的计划,排序就在最后一个连接之前。在错误计划的情况下,因为排序在最后一个连接之前,并且排序的估计行数为 5000,SQL Server 决定使用嵌套循环连接,这会减慢查询速度。
我不想使用表连接提示或更改TOP.
在这种情况下,我可以使用哪些策略来获得一致的计划?
此查询大约每 5 分钟运行一次。
performance sql-server execution-plan sql-server-2014 query-performance
我们的应用程序使用 SQL Server 2014,我们遇到了与计划缓存相关的问题。
我们有一个参数化查询,它的执行计划取决于参数值。服务器缓存在某些情况下不是最佳的执行计划,然后将其用于所有后续查询。
细节:
我们有一个由以下列组成的表:
(
[Revision] [bigint] IDENTITY(1,1) NOT NULL,
[UserId] [uniqueidentifier] NOT NULL,
...A WHOLE LOT OF OTHER COLUMNS...
)
Run Code Online (Sandbox Code Playgroud)
这两列的含义很清楚,UserId是记录所属用户的Id,是记录Revision的自增索引。其他列并不重要,但它们存在并影响执行计划。
该表包含 ~40.000.000 行和 ~200.000 个不同UserId值,因此每个用户平均有 200 条记录。行永远不会更新,我们只使用 INSERT 和 DELETE 来修改数据。
我们的应用程序对此表执行以下查询:
SELECT * FROM SampleTable WHERE Revision > {someRevision} AND UserId = {someId}
Run Code Online (Sandbox Code Playgroud)
该表有两个索引:
Revision ascUserId asc, Revision asc当我手动执行此查询时,我看到执行计划取决于someRevision.
如果是比较接近的修订目前的最高值,则服务器使用Clustered Index Seek与Seek Predicate: Revision > someRevision
如果它没有关闭,服务器使用Index Seek …
使用in运算符会影响索引的使用吗?例如,是否有可能WHERE id IN (10)导致优化器忽略索引?
具体来说,我试图从 StackOverflow理解这个答案。问题询问为什么没有使用索引(在 MySQL 中),答案表明这可能是由于in仅使用了一个值。例如,WHERE id IN (10)可能会忽略索引,而WHERE id=10会很好。
我在 Google 上短暂浏览了一下,浏览了一些 MySQL 文档,但找不到任何in影响优化器使用索引的决定的参考。既不具有单个值,也不具有多个值。
假设这些IN值与它们正在比较的列具有相同的数据类型,它们会影响索引使用吗?
我链接到的问题是针对 MySQL,但我在其他数据库中工作,所以我很想知道这是否是关于索引的普遍注意事项,或者它是否是 MySQL 的一个怪癖。
无论您是否为外键创建索引(当然应该这样做),拥有外键对 Oracle 数据库的性能有任何影响吗?
我想知道的一个特定领域是它们是否有助于数据库生成更好的查询计划
performance oracle foreign-key execution-plan query-performance
我有一个麻烦的查询,我们正在尝试调整。我们的第一个想法是采用更大的执行计划的一部分并将这些结果存储到中间临时表中,然后执行其他操作。
我观察到的是,当我们将数据预先准备到临时表中时,执行计划成本会飙升(22 -> 1.1k)。现在,这样做的好处是允许计划并行执行,这将执行时间减少了 20%,但在我们的情况下,每次执行的 CPU 使用率要高得多,这不值得。
我们正在使用带有旧版 CE 的 SQL Server 2016 SP2。
原始计划(成本 ~20):
https://www.brentozar.com/pastetheplan/?id=ry-QGnkCM
原始 SQL:
WITH Object1(Column1, Column2, Column3, Column4, Column5, Column6)
AS
(
SELECT Object2.Column1,
Object2.Column2,
Object3.Column3,
Object3.Column4,
Object3.Column5,
Object3.Column6
FROM Object4 AS Object5
INNER JOIN Object6 AS Object2 ON Object2.Column2 = Object5.Column2 AND Object2.Column7 = 0
INNER JOIN Object7 AS Object8 ON Object8.Column8 = Object2.Column9 AND Object8.Column7 = 0
INNER JOIN Object9 AS Object3 ON Object3.Column10 = Object8.Column11 AND Object3.Column7 = 0
INNER JOIN …Run Code Online (Sandbox Code Playgroud) performance sql-server optimization execution-plan sql-server-2016 query-performance
对于下面代码的最后两个语句,生成实际的执行计划。您可以看到启动谓词 on@Par1被放置在不同的位置,这完全改变了来自test_fn1函数的实际行数。我需要控制这种行为。
create or alter function dbo.test_fn1(@Par1 varchar(100), @Par2 varchar(1))
returns @t table(item varchar(100))
as
begin
insert into @t (item) select value from STRING_SPLIT(@Par1, @Par2);
return
end
GO
create or alter function dbo.test_fn(@Par1 varchar(100), @Par2 varchar(100))
returns table
as
return (
select s.*
from dbo.test_fn1(@Par2,';') x
inner join sys.objects s on s.name = x.item
where @Par1 = 'CASE1'
)
GO
create or alter function dbo.test_fnx(@Par1 varchar(100), @Par2
varchar(100))
returns table
as
return (
select s.*
from …Run Code Online (Sandbox Code Playgroud) 我创建了一个 varbinary 哈希来检查 2 个表之间的更改。
这是执行计划,我对索引有点困惑,或者确实有更好的编写方式。 https://www.brentozar.com/pastetheplan/?id=HkHmqoczm
连接中的 2 列是目标中的 PK,并且在源中具有非聚集索引。困扰我的一点是排序导致的 tempdb 溢出。
我的老板要我解析存储在表中的一组查询计划,并确定每个计划中存在多少具有无序预取的嵌套循环运算符。我只有大约 100 个查询计划,所以性能不是很重要。我尝试自己做,但很快就糊涂了,无法取得进展。
表的结构:
DROP TABLE IF EXISTS dbo.query_plans;
CREATE TABLE dbo.query_plans (
plan_name VARCHAR(100),
query_xml XML
);
Run Code Online (Sandbox Code Playgroud)
我上传了 T-SQL 以向pastebin上的表添加三个示例查询计划。这是我正在寻找的输出:
????????????????????????????????
? plan_name ? OPERATOR_COUNT ?
????????????????????????????????
? NO_PREFETCH ? 0 ?
? 1_PREFETCH ? 1 ?
? 2_PREFETCH ? 2 ?
????????????????????????????????
Run Code Online (Sandbox Code Playgroud)
我无法回答任何关于为什么我需要这样做的问题。谢谢!
我正在努力理解执行计划中行估计的来源。
declare
@BatchKey INT = 1, @ParentBatchKey INT = 1,
@QuoteRef varchar(50) = 'Q00018249',
@MpanRef varchar(50) = '1425431100004'
SELECT DISTINCT
ISNULL(c.ContractReference,-1) AS [ContractReference] ,
ISNULL(d_cd.ContractDetailsKey,-1) AS [ContractDetailsKey] ,
-1 AccountManagerKey,
-1 SegmentationKey,
ISNULL(d_tpi.TpiKey,-1) AS [TpiKey] ,
ISNULL(d_cu.CustomerKey,-1) AS [CustomerKey] ,
ISNULL(d_p.ProductKey,-1) AS [ProductKey] ,
-1 as PayPointKey,
-1 AS [GspBandingKey], --Not used in Junifer ESOB
ISNULL(d_pps.[ProductPricingStructureKey],-1) AS [ProductPricingStructureKey],
ISNULL(d_tou.TouBandingKey,-1) AS [PricingStructureBandingKey],
-1 AS [VolumePointCategoryKey],
ISNULL(d_ppc.PowerPeriodCategoryKey,-1) AS [PowerPeriodCategoryKey],
ISNULL(d_pcat.[PriceComponentAggregationTypeKey],-1) AS [PriceComponentAggregationTypeKey],
-1 AS [MarginRateBandingKey], --Not used in Junifer ESOB
-1 …Run Code Online (Sandbox Code Playgroud) sql-server optimization execution-plan sql-server-2014 cardinality-estimates
在[dbo].[Programs]表中,列[Id]是主键(不是复合键的 par)。该表上还有很多其他索引。
当我运行这个简单的查询时,SELECT [Id] FROM [dbo].[Programs]执行计划如下:
我的问题是:为什么不只是使用 PK 索引?
性能不是问题,因为该表有 23 行,但我只是觉得它很奇怪,我想了解为什么 SqlServer 是正确的,以及为什么我认为它会更好是错误的。
execution-plan ×10
sql-server ×7
index ×3
performance ×3
optimization ×2
foreign-key ×1
mysql ×1
oracle ×1
plan-cache ×1
query ×1
startup ×1
update ×1
xml ×1
xquery ×1