SELECT这段代码中的三个语句
USE [tempdb];
GO
SET NOCOUNT ON;
CREATE TABLE dbo.persist_test (
id INT NOT NULL
, id5 AS (id * 5)
, id5p AS (id * 5) PERSISTED
);
INSERT INTO dbo.persist_test (id)
VALUES (1), (2), (3);
SELECT id
FROM dbo.persist_test;
SELECT id5
FROM dbo.persist_test;
SELECT id5p
FROM dbo.persist_test;
DROP TABLE dbo.persist_test;
Run Code Online (Sandbox Code Playgroud)
生成这个计划:

为什么SELECT选择持久值的 final生成计算标量运算符?
我正在对性能不佳的存储过程的点点滴滴进行故障排除。程序的这一部分抛出了一个 NO JOIN PREDICATE 警告
select
method =
case methoddescription
when 'blah' then 'Ethylene Oxide'
when NULL then 'N/A'
else methoddescription
end,
testmethod =
case methoddescription
when 'blah' then 'Biological Indicators'
when NULL then 'N/A'
else 'Dosimeter Reports'
end,
result =
case when l.res is null or l.res <> 1 then 'Failed'
else 'Passed'
end,
datecomplete = COALESCE(CONVERT(varchar(10), NULL, 101),'N/A')
from db2.dbo.view ls
join db1.dbo.table l
on ls.id = l.id
where item = '19003'
and l.id = '732820'
Run Code Online (Sandbox Code Playgroud)
视图 ( …
比如说,我们有一个这样的查询:
select a.*,b.*
from
a join b
on a.col1=b.col1
and len(a.col1)=10
Run Code Online (Sandbox Code Playgroud)
假设上述查询使用 Hash Join 并具有残差,则探测键将为col1,残差将为len(a.col1)=10。
但是在查看另一个示例时,我可以看到探针和残差是同一列。以下是对我想说的内容的详细说明:
询问:
select *
from T1 join T2 on T1.a = T2.a
Run Code Online (Sandbox Code Playgroud)
执行计划,突出显示探测和残差:
测试数据:
create table T1 (a int, b int, x char(200))
create table T2 (a int, b int, x char(200))
set nocount on
declare @i int
set @i = 0
while @i < 1000
begin
insert T1 values (@i * 2, @i * 5, @i)
set @i = @i …Run Code Online (Sandbox Code Playgroud) performance sql-server execution-plan database-internals query-performance
产生“Excessive Grant”执行计划警告的条件是什么?
查询内存授予检测到“ExcessiveGrant”,这可能会影响可靠性。授权大小:初始 5128 KB,最终 5128 KB,已用 16 KB。
<Warnings>
<MemoryGrantWarning GrantWarningKind="Excessive Grant"
RequestedMemory="5128" GrantedMemory="5128" MaxUsedMemory="16" />
</Warnings>
Run Code Online (Sandbox Code Playgroud) 当我遇到这个东西时,我正在研究其他东西。我正在生成包含一些数据的测试表并运行不同的查询,以了解编写查询的不同方式如何影响执行计划。这是我用来生成随机测试数据的脚本:
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID('t') AND type in (N'U'))
DROP TABLE t
GO
CREATE TABLE t
(
c1 int IDENTITY(1,1) NOT NULL
,c2 int NULL
)
GO
insert into t
select top 1000000 a from
(select t1.number*2048 + t2.number a, newid() b
from [master]..spt_values t1
cross join [master]..spt_values t2
where t1.[type] = 'P' and t2.[type] = 'P') a
order by b
GO
update t set c2 = null
where c2 < 2048 * 2048 …Run Code Online (Sandbox Code Playgroud) 我有一个带有“TOP (X)”子句的 SQL UPDATE 语句,我正在更新值的行大约有 40 亿行。当我使用“TOP (10)”时,我得到一个几乎立即执行的执行计划,但是当我使用“TOP (50)”或更大时,查询永远不会(至少,在我等待时不会)完成,并且它使用完全不同的执行计划。较小的查询使用带有一对索引查找和嵌套循环连接的非常简单的计划,其中完全相同的查询(在 UPDATE 语句的 TOP 子句中具有不同的行数)使用涉及两个不同索引查找的计划、表线轴、并行性和一堆其他复杂性。
我使用了“OPTION (USE PLAN...)”来强制它使用由较小查询生成的执行计划——当我这样做时,我可以在几秒钟内更新多达 100,000 行。我知道查询计划很好,但 SQL Server 只会在只涉及少量行时自行选择该计划 - 我的更新中任何相当大的行数都会导致次优计划。
我认为并行性可能是罪魁祸首,所以我设置MAXDOP 1了查询,但没有效果 - 这一步已经消失,但糟糕的选择/性能没有。我sp_updatestats今天早上也跑了,以确保这不是原因。
我附上了两个执行计划 - 越短的执行计划也越快。此外,这里是有问题的查询(值得注意的是,我包含的 SELECT 在小行数和大行数的情况下似乎都很快):
update top (10000) FactSubscriberUsage3
set AccountID = sma.CustomerID
--select top 50 f.AccountID, sma.CustomerID
from FactSubscriberUsage3 f
join dimTime t
on f.TimeID = t.TimeID
join #mac sma
on f.macid = sma.macid
and t.TimeValue between sma.StartDate and sma.enddate
where f.AccountID = 0 --There's a filtered index …Run Code Online (Sandbox Code Playgroud) SQL Server 图形执行计划从右到左从上到下读取。生成的输出是否有有意义的顺序SET STATISTICS IO ON?
以下查询:
SET STATISTICS IO ON;
SELECT *
FROM Sales.SalesOrderHeader AS soh
JOIN Sales.SalesOrderDetail AS sod ON soh.SalesOrderID = sod.SalesOrderID
JOIN Production.Product AS p ON sod.ProductID = p.ProductID;
Run Code Online (Sandbox Code Playgroud)
生成这个计划:

这个STATISTICS IO输出:
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'SalesOrderDetail'. Scan count 1, logical reads 1246, physical reads 3, read-ahead reads 1277, …Run Code Online (Sandbox Code Playgroud) 这可能属于意见范畴,但我很好奇人们是否使用跟踪标志 4199作为 SQL Server 的启动参数。对于使用过它的人,您在什么情况下遇到过查询回归?
这似乎是全面的潜在性能优势,我正在考虑在我们的非生产环境中全局启用它,并让它静置几个月以找出任何问题。
2014 年(或 2016 年)是否默认将 4199 中的修复程序纳入优化器?虽然我理解不引入意外计划更改的情况,但在版本之间隐藏所有这些修复似乎很奇怪。
我们使用的是 2008、2008R2,主要是 2012。
create table T(ID int identity primary key)
insert into T default values
insert into T default values
go
select cast(ID as varchar(10)) as ID
from T
where ID = 1
Run Code Online (Sandbox Code Playgroud)
上面的查询在查询计划中有一个警告。
<Warnings>
<PlanAffectingConvert ConvertIssue="Cardinality Estimate" Expression="CONVERT(varchar(10),[xx].[dbo].[T].[ID],0)" />
</Warnings>
Run Code Online (Sandbox Code Playgroud)
为什么它有警告?
字段列表中的强制转换如何影响基数估计?
sql-server execution-plan type-conversion sql-server-2012 cardinality-estimates
我有一个观点,complicated_view-- 有一些连接和 where 子句。现在,
select * from complicated_view (9000 records)
Run Code Online (Sandbox Code Playgroud)
更快,更快,比
select top 500 * from complicated_view
Run Code Online (Sandbox Code Playgroud)
我们说的是 19 秒对 5+ 分钟。
第一个查询返回所有 9000 条记录。如何只获得前 500 名的时间长得可笑?
显然,我将在这里查看执行计划 ---- 但是一旦我弄清楚为什么SQL Server 以次优方式运行“前 500”,我该如何实际告诉它以快速方式运行计划,喜欢坐满桌?
当然,我可能不得不完全重写视图——但很奇怪。
基本上,我将此数据表连接到第 3 方软件,该软件使用select top 500 *无法修改的默认查询预先检查表。因此,除了将此视图转储到实际表中(非常草率)之外,我也无法绕过他们的“前 500 名”附录。
这是 SQL Server 2012。
编辑:不同意重复标志。另一个问题,顶部比所有的都快。这将是预期的行为,返回较少的行。我的情况正好相反。另外,我的理解是 Top 100 是一种与 Top 100+ 不同的算法。我什至不认为重复的问题有正确的答案。也就是说,TOP X 查询将在很早的时候对潜在的大量表进行排序,而不是在它们被聚合/过滤/等之后。为什么是一个谜,但如何显然存在。
performance sql-server execution-plan select top query-performance
execution-plan ×10
sql-server ×10
performance ×3
warning ×2
memory-grant ×1
optimization ×1
select ×1
top ×1