SET STATISTICS XML ON;
DECLARE @x XML = (SELECT 'hi' "@id" FOR XML PATH ('this'), root ('xml'));
Run Code Online (Sandbox Code Playgroud)
表达式中的类型转换 (CONVERT_IMPLICIT(xml,[Expr1001],0)) 可能会影响查询计划选择中的“CardinalityEstimate”
为什么会发生转换?我认为这FOR XML导致结果XML已经是类型。如果这个警告可以/应该被忽略,我如何阻止警告出现在执行计划中(这样当我调试带有类似警告的更大查询时,它不会分散我对实际问题的注意力)?
阅读有关 Microsoft SQL Server 执行计划缓存的不同解释,我对使用存储过程而不是非动态查询的好处感到困惑。
我所说的非动态查询是指一个完全参数化的查询字符串,它不会通过多次调用而改变。
据我了解:
为存储过程和普通查询都缓存了执行计划。
对于存储过程,执行计划是预先计算好的,这比第一次调用存储过程时的普通查询略有优势。
来源在我看来相当矛盾:
MSDN上的Execution Plan Caching and Reuse 文章对参数化查询和存储过程没有区别。这些小节强调了参数化查询的重要性,以便 SQL Server 可以轻松地缓存执行计划。
SQL Server 查询执行计划 – Basics声称相反(强调我的):
在执行即席查询时,查询计划是基于完整代码创建的,因此不同的参数或代码的任何更改都将阻止重用现有计划。
在 DBA.StackExchange 上,对与存储过程的好处相关的答案的评论表明参数化查询与存储过程具有完全相同的效果。
因此,在执行计划没有从缓存中抛出的情况下,为了实验,我想运行数十亿次相当复杂的查询,该查询将从执行计划中受益,并且需要一个改变的参数每次使用存储过程而不是普通的参数化查询在执行计划缓存方面会有什么好处吗?
¹ 在执行计划范围之外,使用存储过程会带来较小的性能优势,例如在网络占用方面:传递存储过程的名称及其参数略好于传递整个查询。这些好处超出了我的问题范围,这纯粹是关于执行计划缓存。
上一个问题:SQL Server 更改执行计划
我们正在使用 SQL Server 2014 开发人员版。
SQL Server 在相同的查询和相同的数据库和 SQL Server 上更改执行计划(我检查了几次)。
如果我使用 AD 帐户从我的开发计算机连接 Management Studio,则完成查询需要 18 秒(大部分时间)。如果我远程连接到服务器并在 Management Studio 中执行查询,则需要 2 秒才能完成。在我同事的机器上,Management Studio 需要 2 秒,如果他与 MVC 应用程序 (Ado.Net) 连接,则需要 18 秒。
SET ANSI_NULLS ON
GO
SET ANSI_PADDING ON
GO
SET ANSI_WARNINGS ON
GO
SET ARITHABORT ON
GO
SET CONCAT_NULL_YIELDS_NULL ON
GO
SET NUMERIC_ROUNDABORT OFF
GO
SET QUOTED_IDENTIFIER ON
GO …Run Code Online (Sandbox Code Playgroud) 如果我有一个返回 query_plan 的查询,例如像这样:
SELECT TOP 1000 st.TEXT
,cp.size_in_bytes
,cp.plan_handle
,QP.query_plan
FROM sys.dm_exec_cached_plans AS cp
CROSS APPLY sys.dm_exec_sql_text(cp.plan_handle) AS st
CROSS APPLY sys.dm_exec_query_plan(cp.plan_handle) AS QP
WHERE cp.objtype = N'Adhoc'
AND cp.usecounts = 1
Run Code Online (Sandbox Code Playgroud)
然后我可以点击一个 query_plan 并将鼠标悬停在最左边的图标上,提示文本将列出估计的子树成本。
有没有办法将它Estimated Subtree Cost作为我的查询的单独列?
我知道这个数字是无单位的,是指大约 20 年前的特定开发人员 PC。即便如此,我认为如果统计数据不是太远,它可能会告诉我查询应该花费多长时间。
我真的很努力地在谷歌上搜索这些信息,但即使是 dba.stackexchange.com 也是空的。
我正在 SQL Server 2008 上执行查询:
SELECT col1
FROM table1
WHERE col2=val2 AND col3=val3
Run Code Online (Sandbox Code Playgroud)
这里 col2 有一个非聚集索引, col1 是PRIMARY KEY,而 col3 没有任何索引。查询执行计划与此类似。

我想知道这里的查询执行是如何工作的。从执行计划中,我可以看到“col2”上的索引查找和“col3”上的键查找(并行显示)。
我有以下表格和内容
create table t(i int primary key, j int, k char(6000))
create index ix on t(j)
insert into t values(1,1,1)
insert into t values(2,1,1)
insert into t values(3,1,1)
insert into t values(4,1,1)
insert into t values(5,1,1)
insert into t values(6,1,1)
insert into t values(7,1,1)
insert into t values(8,2,2)
insert into t values(9,2,2)
select * from t where j = 1
select * from t where j = 2
Run Code Online (Sandbox Code Playgroud)
我真的很困惑为什么第一个 SELECT 只使用Clustered Index Scan (Clustered)而第二个使用Index Seek (NonClustered)和 …
我正在运行以下查询的执行计划:
select m_uid from EmpTaxAudit
where clientid = 91682
and empuid = 42100176452603
and newvalue in('Deleted','DB-Deleted','Added')
Run Code Online (Sandbox Code Playgroud)
下面是执行计划:
我在 ClientId 和 NewValue 列上的 EmpTaxAudit 表上有一个非聚集索引,上面显示为执行的 14.9%:
CREATE NONCLUSTERED INDEX [idx_EmpTaxAudit_clientid_newvalue] ON [dbo].
[EmpTaxAudit]
(
[ClientID] ASC,
[NewValue] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
Run Code Online (Sandbox Code Playgroud)
我还有一个非聚集唯一索引 PK,如下所示:
ALTER TABLE [dbo].[EmpTaxAudit] ADD CONSTRAINT [PK_EmpTaxAudit] PRIMARY KEY NONCLUSTERED
(
[ClientID] ASC,
[EmpUID] ASC,
[m_uid] ASC,
[m_eff_start_date] ASC,
[ReplacedOn] …Run Code Online (Sandbox Code Playgroud) 我注意到涉及 jsonb 列的查询的性能在测试时在 VACUUM ANALYZE 运行之间存在显着差异。分析表格后,我似乎随机得到了完全不同的执行计划。
我在这里使用 Postgres 9.6。我的测试设置如下,我将一个键“x”插入到 jsonb 列“params”中,值在 1 到 6 之间,1 是最稀有的值,6 是最常见的值。我还有一个常规的 int 列“single_param”,其中包含用于比较的相同值分布。:
CREATE TABLE test_data (
id serial,
single_param int,
params jsonb
);
INSERT INTO test_data
SELECT
generate_series(1, 1000000) AS id,
floor(log(random() * 9999999 + 1)) AS single_param,
json_build_object(
'x', floor(log(random() * 9999999 + 1))
) AS params;
CREATE INDEX idx_test_btree ON test_data (cast(test_data.params->>'x' AS int));
CREATE INDEX idx_test_gin ON test_data USING GIN (params);
CREATE INDEX ON test_data(id)
CREATE INDEX ON test_data(single_param)
Run Code Online (Sandbox Code Playgroud)
我正在测试的查询是对结果进行分页的典型查询,我按 …
使用 PostgreSQL 11,我有下表,大约有 4.5 亿行:
postgres=> \d+ sales
Table "public.sales"
Column | Type | Modifiers | Storage | Stats target | Description
-----------------------------------+-----------------------------+------------------------------------+----------+--------------+-------------
created_terminal_id | integer | not null | plain | |
company_id | integer | not null | plain | |
customer_id | integer | | plain | |
sale_no | character varying(20) | not null | extended | |
sale_type | smallint | not null | plain | |
source_type | smallint | not null | plain …Run Code Online (Sandbox Code Playgroud) 我有一个具有复杂逻辑和三个深度级别(嵌套视图)的视图。由于复杂,我无法粘贴执行计划。
由于视图的目的是向数据分析师提供一些业务分析,而他们正在开发报告时,他们会通过执行选择(前 N 个)查询来检查视图样本。
视图中的这个(前 N 个)查询执行得非常糟糕,因为优化器正在为此视图选择不同的执行计划(afaik CQScanTopSortNew)
我尝试对顶部 (N) 用例进行一些优化,例如使用哈希连接,但这会破坏非顶部 (n) 用例。
非顶级 (n) 表现良好。我想知道如何防止优化器在具有 top (n) 子句时选择不同的执行计划,而不会显着改变视图的结构或功能。
例如,如果我在视图中添加一个 select distinct ,优化器总是会选择正确的计划,但视图的功能会发生变化。
sql-server execution-plan sql-server-2016 performance-tuning
execution-plan ×10
sql-server ×7
index ×2
postgresql ×2
xml ×2
explain ×1
index-tuning ×1
json ×1
null ×1
order-by ×1
plan-cache ×1
statistics ×1
t-sql ×1
tuning ×1