是否可以通过sql_id获取当前正在运行的查询的执行计划?
我无法成功:
select
DBMS_SQL_MONITOR.REPORT_SQL_MONITOR
(sql_id=>'b3x6apqyskn7x') report
from dual;
Run Code Online (Sandbox Code Playgroud) 我有一个用于许多报告查询的表。我想知道以“有序”方式读取表格的次数。在聚集索引扫描的执行计划中,可以看到读取是否“有序”。此信息是否在其他地方可用,或者是搜索计划缓存的唯一解决方案?
我是 SQL 执行计划的新手,我正在尝试了解更多有关它们的信息。
我有几个问题。
我们正在解决性能问题,需要维护执行计划以进行故障排除。需要维护执行计划并确保计划缓存在升级到 2019 时不会被刷新。
升级期间计划缓存是否会被清除?有没有办法维护并确保执行计划不被清除?
我有下面的代码,我正在使用参数,但它仍然生成许多重复的 SQL 执行计划。请问出了什么问题以及如何修复?
string cmdString = @"INSERT INTO tb_RA_GLID (glid_StoreNumber,
glid_StoreName,
glid_FirstBusinessDate,
glid_LastBusinessDate,
glid_DateCreated,
glid_TimeCreated,
glid_ExportVersion,
glid_GLMappingVersion,
glid_POSModelOrType,
glid_POSVersion)
VALUES (@StoreNumber , @StoreName , @FirstBusinessDate , @LastBusinessDate , @DateCreated , @TimeCreated , @ExportVersion , @GLMappingVersion , @POSModelOrType , @POSVersion );
"; //SELECT SCOPE_IDENTITY();";
using (SqlConnection conn = new SqlConnection(connectionString))
{
conn.ConnectionString = connectionString;
using (SqlCommand comm = new SqlCommand())
{
comm.Connection = conn;
comm.CommandText = cmdString;
comm.Parameters.AddWithValue("@StoreNumber", columns[1]);
comm.Parameters.AddWithValue("@StoreName", columns[2]);
comm.Parameters.AddWithValue("@FirstBusinessDate", DateTime.ParseExact(columns[3], "yyyyMMdd", CultureInfo.InvariantCulture));
comm.Parameters.AddWithValue("@LastBusinessDate", DateTime.ParseExact(columns[4], "yyyyMMdd", CultureInfo.InvariantCulture));
comm.Parameters.AddWithValue("@DateCreated", DateTime.ParseExact(columns[5], …Run Code Online (Sandbox Code Playgroud) 我的桌子是这样的:
CREATE TABLE [dbo].[ClosedTaskCustomFields](
[ClosedTaskId] [uniqueidentifier] NOT NULL,
[CustomFieldId] [uniqueidentifier] NOT NULL,
[Value] [nvarchar](450) NULL
...
CONSTRAINT [PK_ClosedTaskCustomFields] PRIMARY KEY CLUSTERED
(
[ClosedTaskId] ASC,
[CustomFieldId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
Run Code Online (Sandbox Code Playgroud)
我也有这样的索引用于连接 ClosedTask 表:
CREATE NONCLUSTERED INDEX [IX_ClosedTaskCustomFields_ClosedTaskId] ON [dbo].[ClosedTaskCustomFields]
(
[ClosedTaskId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, …Run Code Online (Sandbox Code Playgroud) 我最近读完 《SQL Server 2008 中的计划缓存》 ,我感到很困惑。看起来,除了完全刷新计划缓存或明确要求重新编译存储过程之外,从 SQL Server 2008 开始,存储过程的重新编译都是在语句级别而不是存储过程级别完成的。
那么,除了显式刷新缓存或要求重新编译(例如WITH RECOMPILE)之外,什么可以在 SQL Server 2019 中重新编译完整的存储过程,而不仅仅是重新编译单个语句呢?
举一个我感到困惑的例子,请考虑以下过程。
CREATE PROCEDURE FOO AS
BEGIN
SELECT * INTO #temp1 FROM table1
INSERT BAR1 SELECT * FROM #temp1
INSERT BAR2 SELECT * FROM #temp1
END
Run Code Online (Sandbox Code Playgroud)
我可以想到很多可能导致SELECT * INTO #temp1 FROM table1重新编译的事情,但是如果没有下一行也重新编译,那么重新编译会很奇怪。这让我觉得 SQL Server 中一定有一些东西会导致整个存储过程重新编译。
stored-procedures t-sql execution-plan recompile sql-server-2019
为什么 SQL 查询/执行计划通常从右到左解释?
英语是一种从左到右的书面语言。即使出于某种原因 SQL 向后制定计划,数据仍然只是屏幕上的像素。
没有理由不从左到右显示它。
对大型表执行 UPDATE 语句后,执行计划会显示包含更新列的索引(所有非聚集索引)的更新。
在每次索引更新之前,都有一个 Eager Spool 操作符,后面跟着一个非常昂贵的 Sort。
总的来说,索引的更新消耗了大约50%的执行时间。
有没有办法优化索引并最小化成本?
即使我添加了所有建议的索引,我的存储过程有时也会花费很长时间。我不断收到查询必须等待内存授予 查询计划可以在这里找到:查询计划
sql-server stored-procedures execution-plan query-performance
execution-plan ×10
sql-server ×8
plan-cache ×3
t-sql ×2
index-spool ×1
oracle ×1
parameter ×1
recompile ×1