我有一个 SQL Server 2012 数据库。我注意到Reason for early termination of statement optimization
一些查询的值,并且都给出了Good Enough Plan Found
. 现在我的问题是:
是否有 DMV 或扩展事件来列出由于找到 Good Enough Plan 以外的原因而终止优化的所有查询?我参考了以下两篇文章,其中没有列出完整的可能性列表。[此外,他们在我的数据库中给了我不同的结果]。
我有一张Employee
有 100 万条记录的表。我有以下 SQL 用于在 Web 应用程序中分页数据。它工作正常。但是,我认为的一个问题是 - 派生表tblEmployee
选择表中的所有记录Employee
(以创建 MyRowNumber
值)。
我认为,这会导致选择Employee
表中的所有记录。
真的那么有效吗?或者 SQL Server 是否也被优化为只从原始Employee
表中选择 5 条记录?
DECLARE @Index INT;
DECLARE @PageSize INT;
SET @Index = 3;
SET @PageSize = 5;
SELECT * FROM
(SELECT ROW_NUMBER() OVER (ORDER BY EmpID asc) as MyRowNumber,*
FROM Employee) tblEmployee
WHERE MyRowNumber BETWEEN ( ((@Index - 1) * @PageSize )+ 1) AND @Index*@PageSize
Run Code Online (Sandbox Code Playgroud) 我在 SQL Server 2012 中遵循了我的实际查询的简化版本。从 Containers 表中选择数据时,它在搜索谓词中有一个标量运算符。
这个搜索谓词中标量运算符的目的是什么?
CREATE TABLE #EligibleOrders (OrderID INT PRIMARY KEY,
StatusCD CHAR(3),
CreatedOnDate DATETIME
)
--insert logic into #EligibleOrders
--Final Query
SELECT T2.OrderID ,olic.LineItemID,
SUM(c.quantity) AS ShippedQty,
COUNT(DISTINCT c.ContainerID) AS ShippedCases
FROM #EligibleOrders T2
INNER JOIN dbo.OrderLineItemContainers (NOLOCK) AS olic
ON olic.OrderID = T2.OrderID
INNER JOIN dbo.Containers (NOLOCK) AS c
ON olic.Containerid = c.Containerid
GROUP BY T2.OrderID ,olic.LineitemID
OPTION (MAXDOP 1)
Run Code Online (Sandbox Code Playgroud)
执行计划
寻求谓词
我有一个 SQL Server 2012 数据库。是否可以获得数据库中所有表的最后截断时间?
注意:恢复模式SIMPLE
在我的场景中。如果我将其更改为可以FULL
吗?
我有一个基于SQL Server 2005
. 我在这些表上创建了索引。但是当我写一个带JOIN
条件的查询时,返回的实际行数太高,而估计的行数更少。并且查询计划使用嵌套循环。[查询计划图如下。] 由于这些是新表,我认为通常的陈旧统计数据不是这里的原因。
我可以通过使用NOT EXISTS
(如查询 2 中所示)重写此查询,并减少实际行数。但是我还有其他要求可以使用 LWTest 表获取详细信息INNER JOIN
——大量实际行是一个问题。
那么,即使有索引和统计信息,为什么实际行数仍然如此之高,有什么线索吗?可以做些什么来降低它?
注意:TransmittedManifests 中的行数 –904。LWTest 中的行数 -- 829785
更新
注 2:Compatibility_Level 为 90。查询 1 的运行时间为 64 毫秒。查询 2 已用时间为 6 毫秒。
注 3:在这两个表上尝试了 OPTION (RECOMPILE)、重建索引和 UPDATE STATISTICS WITH FULLSCAN。但实际的行数仍然很高。
感谢 Martin Smith 提供每次执行计数(估计)和总计数(实际)差异的详细信息。实际行是所有执行的计数,估计是每次执行的计数。估计行数、实际行数和执行计数。
对于查询 1,ActualExecutions
LWTest 表的="904"。
询问
DBCC FREEPROCCACHE
GO
DBCC DROPCLEANBUFFERS
GO
SET STATISTICS IO ON
PRINT 'BEGIN -----------------------------------------'
--Query 1
SELECT T.[Manifest]
FROM dbo.TransmittedManifests T …
Run Code Online (Sandbox Code Playgroud) 来自sys.dm_exec_query_stats 的Query_hash 定义 是:
query_hash:对查询计算的二进制哈希值,用于识别具有相似逻辑的查询。您可以使用查询哈希来确定仅在文字值上有所不同的查询的聚合资源使用情况。
但是当我搜索一个特定的 query_hash(如下所示)时,我得到了多个查询文本,这些文本在逻辑和size_in_bytes
(计划)上有很大差异。
注意:我使用的是 SQL Server 2016
DECLARE @QueryHashTest BINARY(8)
SET @QueryHashTest = CONVERT(BINARY(8), 'Ð…U¹üŒv¿')
SELECT
QCP.objtype
,qStat.query_hash,
CONVERT(VARCHAR(100), qStat.query_Hash) AS VARCHAR_query_hash
,sText.text AS QueryText
,QCP.size_in_bytes
,qStat.creation_time
,qp.query_plan
FROM (
SELECT query_hash,
COUNT(query_hash) AS PlanCount
FROM sys.dm_exec_query_stats
GROUP BY query_hash
) AS MultipleQ
INNER JOIN sys.dm_exec_query_stats qStat ON MultipleQ.query_hash = qStat.query_hash
INNER JOIN sys.dm_exec_cached_plans QCP
ON QCP.plan_handle = qStat.plan_handle
CROSS APPLY sys.dm_exec_sql_text(qStat.sql_handle) AS sText
CROSS APPLY sys.dm_exec_query_plan(qStat.plan_handle) AS qp
WHERE PlanCount > …
Run Code Online (Sandbox Code Playgroud) 阅读以下博客后,我明白hash match
聚合原因blocking
。使用适当的索引,它可以作为stream aggregate
.
我有一个数据库,其中包含 200 多个多年前创建的表。我正在尝试通过 group by 查找当前正在使用hash match
聚合运算符的所有查询。我发现的一种可能性是使用 dmv,如下所示。但我不知道如何过滤它以仅列出带有hash match
聚合运算符的查询。如何实现这一目标?此外,从大局来看,除了遵循 dmv 之外,还有哪些其他选项可以获取此信息?
SELECT cp.objtype AS ObjectType,
OBJECT_NAME(st.objectid,st.dbid) AS ObjectName,
cp.usecounts AS ExecutionCount,
st.TEXT AS QueryText,
qp.query_plan AS QueryPlan
FROM sys.dm_exec_cached_plans AS cp
CROSS APPLY sys.dm_exec_query_plan(cp.plan_handle) AS qp
CROSS APPLY sys.dm_exec_sql_text(cp.plan_handle) AS st
WHERE st.TEXT LIKE '%GROUP%'
Run Code Online (Sandbox Code Playgroud) performance sql-server aggregate execution-plan performance-tuning
我的系统中有一个名为“Orders”的现有表。OrderID 是这个表中的主键——它是一个聚集索引。我为“OrderCompanyDetails”设计了一个新表,如下所示。它1-to-1
与 Orders 表有关系。在新表中,OrderID 被保留为集群主键。
只有在订单获得批准后,数据才会插入到新表中。因此插入到新表中的 OrderID 可能不是按顺序排列的。OrderID 10 可能会在 OrderID 5 之前插入,具体取决于哪个订单首先被批准。
在 OrderID 上拥有聚集索引有助于我的查询。但是聚集索引位于以随机序列获取数据的列上。这是一个糟糕的索引设计吗?如果是,我是否应该添加一个名为 OrderCompanyDetailID 的新无意义标识列并将其设为聚集索引?
CREATE TABLE [dbo].[Orders]
(
[OrderID] [int] IDENTITY(1,1) NOT NULL,
[OrderType] [char](3) NOT NULL,
[StatusCD] [char](10) NOT NULL,
[CreatedOnDate] [datetime] NOT NULL CONSTRAINT [DF__Orders__CreatedOn] DEFAULT (getdate()),
CONSTRAINT [PK_Orders] PRIMARY KEY CLUSTERED
(
[OrderID] ASC
)
)
CREATE TABLE [dbo].[OrderCompanyDetails](
[OrderID] [int] NOT NULL,
[POCompanyCD] [char](4) NULL,
[VendorNo] [varchar](9) NULL,
[CreatedOnDate] [datetime] NOT NULL CONSTRAINT [DF_OrderCompanyDetails_CreatedOn] DEFAULT (getdate()),
CONSTRAINT [PK_OrderCompanyDetails] PRIMARY KEY …
Run Code Online (Sandbox Code Playgroud) 我正在尝试找出具有Probe Residual
.
需要了解以下内容
Probe Residual
以下是我的一次尝试——但我被困在获取其他细节上。如何获取这些详细信息?
注意:我使用的是 SQL Server 2012
WITH XMLNAMESPACES
(
DEFAULT 'http://schemas.microsoft.com/sqlserver/2004/07/showplan'
)
SELECT
DECP.cacheobjtype,
DECP.objtype,
DECP.plan_handle,
DEQP.objectid,
DEQP.query_plan,
DEST.[text]
FROM sys.dm_exec_cached_plans AS DECP
CROSS APPLY sys.dm_exec_query_plan(DECP.plan_handle) AS DEQP
CROSS APPLY sys.dm_exec_sql_text(DECP.plan_handle) AS DEST
WHERE
1 = DEQP.query_plan.exist(
'//RelOp[
@PhysicalOp = "Hash Match"
]')
Run Code Online (Sandbox Code Playgroud)
甲探头残余例
下面引用 Grant Fritkey 和 Rob Farley 的博客/文章
sql-server ×9
performance ×2
aggregate ×1
index ×1
optimization ×1
plan-cache ×1
truncate ×1
xml ×1