我已经捕获了特定查询的实际查询计划。
在此之后,我更改了一些内容(包括更新统计信息)并重新运行该特定查询。现在实际的查询计划是不同的(这是有道理的)。
查询现在运行得更快了。我很好奇新的执行计划是否与此有关,因为其他更改(对 IO 设置、VM 设置、sql 实例重新启动等的更改)也可能导致性能提高。为了测试这一点,我想再次运行查询,并尝试强制 SQL Server 使用旧的执行计划。
问题:有没有办法使用用户提供的执行计划重新运行查询,甚至直接从这样的计划运行查询?
这是我试图弄清楚的:
所以底线:这可能吗?如果是这样:如何?
我一直注意到我们的查询计划缓存存在一些我认为不寻常的问题,其中缓存中的计划从未超过一天。
通过运行以下查询(由Kimberly Tripp 提供),它表明大多数计划(4.5Gb 的 6Gb 缓存计划或 44813 的 ~50000)是使用计数为 1 的临时查询。
SELECT objtype AS [CacheType]
, count_big(*) AS [Total Plans]
, sum(cast(size_in_bytes as decimal(18,2)))/1024/1024 AS [Total MBs]
, avg(usecounts) AS [Avg Use Count]
, sum(cast((CASE WHEN usecounts = 1 THEN size_in_bytes ELSE 0 END) as decimal(18,2)))/1024/1024 AS [Total MBs - USE Count 1]
, sum(CASE WHEN usecounts = 1 THEN 1 ELSE 0 END) AS [Total Plans - USE Count 1]
FROM sys.dm_exec_cached_plans
GROUP BY objtype
ORDER …Run Code Online (Sandbox Code Playgroud) 我有一个很大的查询要调整。我写了很多查询,但没有做很多调整。我已经包含了 SQL Sentry Plan Explorer Free (SSPEF) 的屏幕截图:

在计划的上述部分中,表 pb_WorkRquestLog 包含 229,001 行。但是,查询计划显示大约。3.48 亿行(229,001 x 1,520 次迭代):

没有 where 子句,因此查询使用的是聚集索引扫描。我已经用 FULLSCAN 重建了所有索引并更新了所有统计信息。
这部分计划正在执行的代码是:
select distinct
wrs.ServiceKey
, owner.DepartmentName AS GroupName
, owner.UserName AS UserId
, owner.WRLCreateDateTime
, owner.WRLNotes
, wrx.CreatedDate as WRCreateDateTime
, wrx.Id
, wrx.Description
, cast(wrx.Notes as varchar(2500)) as Notes
from
prism72ext.dbo.pb_WorkRequestService wrs
Join prism72ext.dbo.pb_WorkRequest wrx on (wrs.WorkRequestId = wrx.Id and wrx.Status = 'Incomplete')
left join (
select
wl.WorkRequestId
, d.Name AS DepartmentName
, u.UserName
, wl.CreatedDate as …Run Code Online (Sandbox Code Playgroud) performance sql-server-2005 execution-plan query-performance performance-tuning
我有一个这样的程序(简化):
CREATE PROCEDURE test @userName VARCHAR(64)
SELECT *
FROM member M
INNER JOIN order O
ON M.MemberId=O.MemberId
WHERE M.Username = @userName
Run Code Online (Sandbox Code Playgroud)
Member 表的 Username 列上有一个非聚集索引。
计划缓存显示隐式转换如下:
查找键[1]:前缀:[MyDatabase].[dbo].[Member].Username = Scalar Operator(CONVERT_IMPLICIT(varchar(64),[@Username],0))
我只是想知道是什么导致了这种隐式转换,因为参数和字段数据类型“UserName”都是 varchar(64)?
像这样从框架调用 SP:
EXEC test @Username=N'webSite.com'
Run Code Online (Sandbox Code Playgroud)
谢谢你。
performance sql-server stored-procedures execution-plan sql-server-2008-r2 query-performance
在 PostgreSQL 9.3 中,我试图在一个很少使用的(占总记录的 0.00001%)布尔列上创建一个有效的索引。为此,我在 SO 上发现了这篇文章: https //stackoverflow.com/a/12026593/808921
我正在尝试利用 Erwin Brandstetter 推荐的 PostgreSQL 的“部分索引”功能。我已经有一个包含几百万条记录的表,我想将索引添加到该表中,如下所示:
CREATE INDEX schema_defs_deprovision ON schema_defs (deprovision)
WHERE deprovision = 0;
Run Code Online (Sandbox Code Playgroud)
(绝大多数记录都会有 deprovision = 1)
问题是,当我尝试将此索引与最简单的查询一起使用时,PostgreSQL 就好像它不存在一样:
explain select * from schema_defs where deprovision = 0;
Seq Scan on schema_defs (cost=0.00..1.05 rows=1 width=278)
Filter: (deprovision = 0)
Run Code Online (Sandbox Code Playgroud)
真正奇怪的是,我发现如果这个索引是在表中有数据之前创建的,那么它确实可以正常工作。不相信我?以下是一些证明这一点的 SQL Fiddle 条目:
插入后创建的部分索引(索引不起作用)
插入前创建的部分索引(索引正常工作)
在这两个中,只需展开“查看执行计划”链接即可查看我在说什么。
所以,我的问题是 - 我必须做什么才能让 PostgreSQL 在创建索引之前开始在其中包含数据的表上使用部分索引?
顺便说一句,我也是 SQL Fiddle 的开发人员,这个问题与我正在为此进行的一项新开发工作有关。
两台服务器,Development 和 Live。实时服务器是一个 Amazon RDS SQL Server Web 实例。两台服务器都具有相同的架构和数据。几何列上有一个很好的空间索引。在我的开发服务器上,查询在 < 30 毫秒内执行。在实时服务器上,查询需要 > 20 分钟。
检查执行计划表明它们完全不同。一方面,在我的开发环境中,查询是并行化的,而在实时服务器上则不是。
如果您对原因或如何最好地诊断问题有任何见解,我将不胜感激。
DECLARE @geoBoundary geometry;
SET @geoBoundary = geometry::STGeomFromText('POLYGON((407439.5 108792.25, 408022.5 108792.25, 408022.5 108575.75, 407439.5 108575.75, 407439.5 108792.25))', '0');
SELECT
ogr_geometry.ToString() AS strGeometry
,ogr_geometry
FROM inspire as geo
WHERE geo.ogr_fid IN
(
SELECT
geo.ogr_fid
FROM .inspire as geo
WHERE
(
(@geoBoundary.STContains(geo.ogr_geometry) = 1)
)
UNION
SELECT
geo.ogr_fid
FROM .inspire as geo
WHERE
(
(@geoBoundary.STOverlaps(geo.ogr_geometry) = …Run Code Online (Sandbox Code Playgroud) 我有一个带有多个执行计划的查询,与第二个计划相比,授予一个计划的内存是巨大的
当嵌套循环联接的外部表具有将结果过滤为小输入的谓词时,会出现问题,但批处理排序似乎使用与整个外部表等效的基数估计值。这可能会导致感知到过多的内存授予,这在非常并发的服务器中可能会产生多种副作用,例如 OOM 条件、计划缓存驱逐的内存压力或意外的 RESOURCE_SEMAPHORE 等待。我们已经看到,匹配此模式的单个查询实际上可以在高端机器(1TB+ RAM)上获得几 GB 的授予内存。
到目前为止,一种选择是使用跟踪标志 2340 全局禁用此功能,如 KB 2801413 中所述。但是,在 SQL Server 2016 RC0 中,我们已更改行为以保持优化的优势,但现在最大授予限制基于在可用的内存授予空间上。这种改进也转化为更好的可扩展性,从某种意义上说,可以用更小的内存占用执行更多的查询。我们正在考虑将此行为反向移植到即将推出的已将此行为移植到 SQL Server 2014 Service Pack 2,并像往常一样为市场上的版本提供附加值。
这正是我所看到的,但是我使用的是 SQL Server 2016 Enterprise。
这些是执行计划
https://www.brentozar.com/pastetheplan/?id=SJ0mYAy0b
https://www.brentozar.com/pastetheplan/?id=BJzutC1R-
我的问题是
2个执行计划的原因是什么?
优化器正在使用顶部执行计划,我强迫它使用较低的计划,但过了一段时间它又回到顶部执行计划,有什么原因吗?
如何解决这个问题?这个问题导致应用程序崩溃(有很多RESOURCE_SEMAPHORE等待,应用程序变得无响应)?我应该使用提示:DISABLE_OPTIMIZED_NESTED_LOOP还是 Trace Flag 2340?
注意:我检查了 XML,两个计划都有 NestedLoops Optimized="false"
我有一个基本[UserActivity]表,它捕获了一个ActivityTypeIdperUserId和ActivityDate发生 Activity 的时间。
我写一个查询/存储过程中允许的输入@UserId,@ForTypeId,还有@DurationInterval和@DurationIncrement基于动态返回的结果ň若干秒/分钟/小时/天/月/年。鉴于其中的datepart参数DATEADD/DATEDIFF不允许使用参数,为了在WHERE子句中获得所需的结果,我不得不重新使用一些技巧。
最初我使用 编写查询DATEDIFF,但在编写并查看执行计划后,我立即想起它不是 SARGable 函数(以及精度级别可以为闰年下降的某些日期提供的事实)。因此,我重新编写了查询以利用DATEPART我会命中索引查找而不是索引扫描并且通常性能更好的想法。
不幸的是,我发现将查询编写为DATEADD提供了相同的结果:正在执行索引扫描,并且查询优化器没有针对[ActivityDate].
我读阿龙贝特朗的博客文章,“业绩惊喜和假设:DATEADD”,并实现了他描述的变化CONVERT的DATEADD部分成等价的datetime2,由于涉及怪异弄虚作假列定义datetime2。但是,即使这样做了,问题仍然存在。
为了更好地说明这种情况,这里有一个可比较的表定义。
DROP TABLE IF EXISTS [dbo].[UserActivity]
IF OBJECT_ID('[dbo].[UserActivity]', 'U') IS NULL
BEGIN
CREATE TABLE [dbo].[UserActivity] (
[UserId] [int] NOT NULL
,[UserActivityId] [bigint] IDENTITY(1,1) NOT NULL
,[ActivityTypeId] [tinyint] NOT …Run Code Online (Sandbox Code Playgroud) performance index sql-server execution-plan query-performance
我遇到了慢查询问题,这是由计划程序检查每个继承的表而不是仅具有约束的表引起的。
我有一个名为“search_result”的 0 行表。该表有几个继承的表,它们具有基于“极化”的不同约束,我们所有的数据都驻留在该表中。例如:
CREATE TABLE search_result_positive
(
CONSTRAINT search_result_positive_polarization_check CHECK (polarization = (1))
)
INHERITS (search_result);
CREATE TABLE search_result_negative
(
CONSTRAINT search_result_negative_polarization_check CHECK (polarization = (-1))
)
INHERITS (search_result);
CREATE TABLE search_result_unpolarized
(
CONSTRAINT search_result_unpolarized_polarization_check CHECK (polarization IS NULL)
)
INHERITS (search_result);
Run Code Online (Sandbox Code Playgroud)
例如,当我使用“WHEREpolarization = 1”执行查询时,查询规划器将显示它只检查了“search_result_positive”:表,这是所需的行为。
但是,当查询是“WHEREpolarization IS NULL”时,它会检查每个表,花费大量时间。以下是“search_result_positive”的示例:
SELECT "search_result".* FROM "search_result" WHERE (polarization = 1) ORDER BY published_on DESC LIMIT 20;
Limit (cost=0.44..17.65 rows=20 width=2027) (actual time=3.638..3.666 rows=20 loops=1)
-> Merge Append (cost=0.44..249453.67 rows=289872 width=2027) (actual time=3.637..3.663 rows=20 …Run Code Online (Sandbox Code Playgroud) 我有一段 SQL 似乎在环境 A 中运行得非常快,但完全相同的查询在环境 B 中运行得非常慢!
环境应该是相同的,所以我应该做什么和/或我应该在哪里查看查询为什么不执行相同?
execution-plan ×10
sql-server ×7
performance ×5
index ×2
postgresql ×2
amazon-rds ×1
memory-grant ×1
optimization ×1
plan-cache ×1
spatial ×1
statistics ×1